Простой пример связывания массива не работает

1

Я очень новичок в xaml и я пытаюсь понять проблему Binding. У меня проблема с Array Binding к Array Binding. Я создал этот очень простой пример: у меня есть панель стека с тремя изображениями. Каждое изображение имеет RotationTransform. Каждый Angle получается элементом массива (массив - DependencyProperty под названием Rotations). Это простой файл xaml:

<StackPanel Orientation="Vertical">
        <Image Source="/Assets/knife.png" Width="50" Height="100" Stretch="Uniform" RenderTransformOrigin="0.5,0.5">
            <Image.RenderTransform>
                <RotateTransform Angle="{Binding ElementName=pageRoot, Path=Rotations[0], Mode=OneWay}"/>
            </Image.RenderTransform>
        </Image>

        <Image Source="/Assets/fork.png" Width="50" Height="100" Stretch="Uniform" RenderTransformOrigin="0.5,0.5">
        <Image.RenderTransform>
            <RotateTransform Angle="{Binding ElementName=pageRoot, Path=Rotations[1], Mode=OneWay}"/>
        </Image.RenderTransform>
        </Image>

        <Image Source="/Assets/spoon.png" Width="50" Height="100" Stretch="Uniform" RenderTransformOrigin="0.5,0.5">
            <Image.RenderTransform>
                <RotateTransform Angle="{Binding ElementName=pageRoot, Path=Rotations[2], Mode=OneWay}"/>
            </Image.RenderTransform>
        </Image>

        <Button x:Name="actionButton" Content="Try Binding!" 
                Click="Op_Click"/>            
    </StackPanel>

И это мой класс c#:

public sealed partial class MainPage : Page
    {        
        public static readonly DependencyProperty RotationsProperty = DependencyProperty.Register("Rotations", typeof(double[]), typeof(MainPage),
            new PropertyMetadata(new double[3]));

        public double[] Rotations
        {
            get { return (double[])GetValue(RotationsProperty); }
            set { SetValue(RotationsProperty, value); }
        }

        private void Op_Click(object sender, RoutedEventArgs e)
        {
            Rotations[0] = 180;
            Rotations[1] = 130;
            Rotations[2] = 350;
        }

        public MainPage()
        {
            this.InitializeComponent();
            Rotations[0] = 20;
            Rotations[1] = 90;
            Rotations[2] = 180;
        }
    }

Связывание работает только в первый раз (во время запуска). Когда я нажимаю на кнопку (меняя массив Rotations), привязка не работает, и она полностью игнорируется из моих изображений.

Это очень простой пример, поэтому ясно, что я что-то пропустил в связи с проблемой Binding.

Теги:
xaml
wpf
dependency-properties
binding

3 ответа

0
Лучший ответ

Хорошо, я нашел решение с использованием ObservableCollection: файл xaml остается прежним, но класс c# меняет этот способ:

public sealed partial class MainPage : Page
    {        
        public static readonly DependencyProperty RotationsProperty = 
            DependencyProperty.Register("Rotations", typeof(ObservableCollection<double>), typeof(MainPage),
            new PropertyMetadata(new ObservableCollection<double>()));       

        public ObservableCollection<double> Rotations
        {
            get { return (ObservableCollection<double>)GetValue(RotationsProperty); }
            set { SetValue(RotationsProperty, value); }
        }

        private void Op_Click(object sender, RoutedEventArgs e)
        {
            Rotations[0] = 180;
            Rotations[1] = 180;
            Rotations[2] = 320;
        }

        public MainPage()
        {
            this.InitializeComponent();
            Rotations.Add(90);
            Rotations.Add(90);
            Rotations.Add(90);
        }
    }
1

Я думаю, проблема в том, что вы меняете значение записей в массиве, но вы не меняете сам массив, поэтому "SetValue" не вызывается. Вы можете попытаться установить "Вращения" в новый массив.

this.Rotations = new double[] {180, 130, 350};

Изменение: я проверил ваш код с моими изменениями, и это сработало. Еще одно предложение было бы написать метод setter для записей массива и вызвать "SetValue" или (как предлагается в комментариях) использовать "INotifyPropertyChanged" вместо DependencyProperty.

  • 0
    М-м-м ... я попробую через минуту, но это очень странно ... мне нужно генерировать новый массив каждый раз, когда я изменяю элемент? Это безумие :) Нет ли другого способа для этого?
  • 0
    следует использовать интерфейс INotifyPropertyChanged, после обновления члены Array вызывают событие, используя имя свойства в качестве параметра
Показать ещё 4 комментария
0

Попробуйте приведенный ниже код:

Xaml:

<StackPanel Orientation="Vertical">
    <Image Source="/Assets/knife.png" Width="50" Height="100" Stretch="Uniform" RenderTransformOrigin="0.5,0.5">
        <Image.RenderTransform>
            <RotateTransform Angle="{Binding Rotations[0], Mode=OneWay}"/>
        </Image.RenderTransform>
    </Image>

    <Image Source="/Assets/fork.png" Width="50" Height="100" Stretch="Uniform" RenderTransformOrigin="0.5,0.5">
    <Image.RenderTransform>
        <RotateTransform Angle="{Binding Rotations[1], Mode=OneWay}"/>
    </Image.RenderTransform>
    </Image>

    <Image Source="/Assets/spoon.png" Width="50" Height="100" Stretch="Uniform" RenderTransformOrigin="0.5,0.5">
        <Image.RenderTransform>
            <RotateTransform Angle="{Binding Rotations[2], Mode=OneWay}"/>
        </Image.RenderTransform>
    </Image>

    <Button x:Name="actionButton" Content="Try Binding!" 
            Click="Op_Click"/>            
</StackPanel>

В коде позади установлен DataContext, как показано ниже:

this.DataContext = this;

  • 0
    Нет, ничего не меняется ... все равно спасибо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню