【问题标题】:Array Binding simple example doesn't work数组绑定简单示例不起作用
【发布时间】:2023-04-03 06:54:01
【问题描述】:

我对@9​​87654321@ 很陌生,我正在尝试了解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 数组)时,绑定不起作用,我的图像完全忽略了它。

这是一个非常简单的示例,因此很明显我错过了有关绑定问题的一些内容。

【问题讨论】:

    标签: c# wpf xaml binding dependency-properties


    【解决方案1】:

    好的,我找到了使用 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);
            }
        }
    

    【讨论】:

      【解决方案2】:

      试试下面的代码:

      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;

      【讨论】:

        【解决方案3】:

        我猜问题是您更改了数组条目的值,但您没有更改数组本身,因此不会调用“SetValue”。您可以尝试将“Rotations”设置为新数组。

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

        编辑:我用我的更改测试了您的代码并且它有效。另一个建议是为数组条目编写一个 setter 方法并调用“SetValue”或(如 cmets 中建议的那样)使用“INotifyPropertyChanged”而不是 DependencyProperty。

        【讨论】:

        • 嗯...我一会儿试试,但这很奇怪...每次修改元素时都必须生成一个新数组吗?这太疯狂了 :) 没有其他方法可以解决这个问题吗?
        • 您应该使用接口 INotifyPropertyChanged ,在更新数组成员后使用属性名称作为参数引发事件
        • 或者他可以保留 DependencyProperty,只写一个 setter 方法来更新数组值,然后调用 SetValue。
        • @stsur:不需要使用 INotifyPropertyChanged,检查我自己的答案。我赞成 lukegv 答案,因为它有效,但效率很低。
        • 我知道,但我试图让你的项目在没有大改动的情况下工作。您使用了一个数组,我想向您展示您需要更新数组本身,因为如果数组条目被更改,则没有通知,但可以肯定我的解决方案不是“漂亮”的编程;)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-01
        • 2015-11-23
        • 2016-03-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多