WPF如何将数组设置为属性

时间:2019-09-16 16:31:21

标签: c# arrays wpf

我正在使用WPF,但我有一组要在运行时更改其颜色的椭圆形。这是我的代码

Color[] ellipsecolor = new Color[13];
public event PropertyChangedEventHandler PropertyChanged;

    private void onPropertyChanged(String propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

我想这样做:

Ellipse x:Name="Spot5" Fill="Gray" StrokeThickness="6" Width="40" 
Height="40" Margin="219,211,241,249" MouseDown="Ellipse_MouseDown"
  ..
 SolidColorBrush Color= "{Binding ellipsecolor[0],IsAsync=True}"/>

但是我不确定是否可以做到。 能做到吗?

2 个答案:

答案 0 :(得分:1)

无需使用数组。您可以在xaml中索引到ObservableCollection中,类似于索引到数组中。不过,您的集合类型需要实现INotifyPropertyChanged。理想情况下,您将创建一个从Color继承的类型并实现INotifyPropertyChanged,但是由于Color类是密封的,所以这是不可能的。

但是,使用您自己的类型包装Color应该可以。

 class MyColor : INotifyPropertyChanged
 {        
        public event PropertyChangedEventHandler PropertyChanged;

        private Color _color;

        public Color color
        {
            get
            {
               return _color;
            }

            set
            {
               _color = value;
               OnPropertyChanged("color");
            }
        }

        void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
  }   

在适当的地方实例化集合。

   ObservableCollection<MyColor> ellipseColors = new ObservableCollection<MyColor>();

然后绑定到xaml中索引的MyColor对象的color属性。

Color= "{Binding Path=ellipseColors[0].color, IsAsync=True}"/>

有关某些想法,请点此信。 Binding to an array element

更新

public partial class Wafer : UserControl
{
    private string _waferLocation;

    ObservableCollection<MyColor> ellipseColors;

    private void WaferLoaded(object sender, RoutedEventArgs e)
    {
      ellipseColors = new ObservableCollection<MyColor>();          

      for (int i = 0; i < 13; i++)
      {
          ellipseColors.Add(new MyColor { color = Brushes.Gray });               
      }

    }

    class MyColor : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private SolidColorBrush _color;

        public SolidColorBrush color
        {
            get
            {
                return _color;
            }

            set
            {
                _color = value;
                OnPropertyChanged("color");
            }
        }

        void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

答案 1 :(得分:0)

不确定使用的是哪种MVVM框架,但是一般的方法是这样:

  1. 在ViewModel层中,为椭圆创建一个VM:

    public class EllipseVM : ObservableObject
    {
        private Color _Color;
        public Color Color
        {
          get => _Color;
          set => Set(ref _Color, value);
        }
    
        private double _X;
        public double X
        {
          get => _X;
          set => Set(ref _X, value);
        }
    
        private double _Y;
        public double Y
        {
          get => _Y;
          set => Set(ref _Y, value);
        }
    }
    
  2. 在主ViewModel中创建这些椭圆的集合:

    public class MainVM : ViewModelBase
    {
        private ObservableCollection<EllipseVM> _Ellipses;
        public ObservableCollection<EllipseVM> Ellipses
        {
          get => _Ellipses;
          set => Set(ref _Ellipses, value);
        }
    }
    
  3. 在您的View层中,创建一个与此集合绑定的ItemsControl

    <ItemsControl ItemsSource="{Binding Ellipses}">
      <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
          <Canvas />
        </ItemsPanelTemplate>
      </ItemsControl.ItemsPanel>
    
      <ItemsControl.ItemTemplate>
        <DataTemplate>
          <Ellipse Fill="{Binding Color}" Width="40" Height="40" />
        </DataTemplate>
      </ItemsControl.ItemTemplate>
    
      <ItemsControl.ItemContainerStyle>
        <Style>
          <Setter Property="Canvas.Left" Value="{Binding X}" />
          <Setter Property="Canvas.Top" Value="{Binding Y}" />
        </Style>  
      </ItemsControl.ItemContainerStyle>
    </ItemsControl>
    

积分

  1. 您可以在运行时向集合中添加任意多个椭圆。由于您的收藏集为ObservableCollection,因此View图层将自动更新。
  2. ItemsControl使用Canvas作为其面板,它使您可以使用X,Y坐标来定位椭圆。这使您可以在运行时放置或移动椭圆。
  3. 请注意,画布属性需要通过ItemContainerStyle而不是ItemTemplate进行设置。这是因为ItemsControl为集合的每个项目生成一个包装器元素。然后将您的DataTemplate放置在该包装器内,因此您需要设置该包装器元素的位置,这正是ItemContainerStyle的作用。
  4. 如果您的VM层不能使用Color类(因为它是一个View级别的库),则可以将EllipseVM的Color属性设置为int类型。然后,您需要在View层中创建一个转换器,以将int的值转换为Color
  5. 我使用了MVVM Light中的帮助程序类(例如ViewModelBaseObservableObject)。如果您使用的是其他框架,请用它们的对应部分替换它们。
  6. 您必须将视图的DataContext设置为MainVM。您可以通过MVVM Light中的ViewModelLocator完成此操作。您也可以直接在XAML或代码隐藏中执行此操作。