我正在使用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}"/>
但是我不确定是否可以做到。 能做到吗?
答案 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框架,但是一般的方法是这样:
在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);
}
}
在主ViewModel中创建这些椭圆的集合:
public class MainVM : ViewModelBase
{
private ObservableCollection<EllipseVM> _Ellipses;
public ObservableCollection<EllipseVM> Ellipses
{
get => _Ellipses;
set => Set(ref _Ellipses, value);
}
}
在您的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>
ObservableCollection
,因此View图层将自动更新。ItemsControl
使用Canvas
作为其面板,它使您可以使用X,Y坐标来定位椭圆。这使您可以在运行时放置或移动椭圆。ItemContainerStyle
而不是ItemTemplate
进行设置。这是因为ItemsControl
为集合的每个项目生成一个包装器元素。然后将您的DataTemplate
放置在该包装器内,因此您需要设置该包装器元素的位置,这正是ItemContainerStyle
的作用。Color
属性设置为int
类型。然后,您需要在View层中创建一个转换器,以将int
的值转换为Color
。ViewModelBase
和ObservableObject
)。如果您使用的是其他框架,请用它们的对应部分替换它们。DataContext
设置为MainVM
。您可以通过MVVM Light中的ViewModelLocator
完成此操作。您也可以直接在XAML或代码隐藏中执行此操作。