首先,在我的应用程序中,我使用Extended WPF Toolkit ColorPicker。
在画布上,我根据反序列化的XML文件绘制了几个矩形(这很有效)。对于每个绘制的矩形,我添加一个ColorPicker,以便应用程序的用户可以更改矩形的颜色。我尝试使用ICommand
界面,但颜色选择器似乎不支持绑定自定义命令,所以我有点卡住而且不知道该怎么做。这是我目前的代码:
<ItemsControl Name="inputs2">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Name="testgrid" Margin="0,0,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock HorizontalAlignment="Left" Grid.Column="0" Text="{Binding Title}" />
<xctk:ColorPicker HorizontalAlignment="Left"
Grid.Column="1"
Name="ClrPcker_Background"
SelectedColor="{Binding Color}"
<!--tryig to bind here???-->
/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我的C#
internal class BackgroundInput
{
public BackgroundInput()
{
}
public string Color { get; set; }
public string Title { get; set; }
}
第二部分:
public override void Draw(Canvas label)
{
Rectangle rect = new Rectangle();
//...... drawing method
label.Children.Add(rect );
}
internal override void AddInputs(ItemsControl inputPanel)
{
inputPanel.Items.Add(new BackgroundInput() { Title = "Backgroundcolor:", Color = BackgroundColor });
}
//both methods get called
因此,每当ColorPicker的颜色发生变化时,我都希望连接的矩形更新它的背景颜色。 ColorPicker似乎不支持Command="..."
和CommandParameter="..."
发送数据,因此我想就如何执行此操作提供建议。谢谢!
修改
我现在拥有的一个小例子。如果用户更改颜色选择器的颜色,我会尝试更改颜色。
修改
我有点工作,但我不认为这是正确的方法。这是我的更新代码:
internal class BackgroundInput
{
private string _bg;
public BackgroundInput()
{
}
public Box Box { get; internal set; }
public string Color
{
get { return _bg; }
set { _bg = value; Box.BackgroundColor = _bg; Box.redraw(); }
}
public string Title { get; set; }
}
矩形代码:
public class Box : Field
{
Canvas label;
Border _border;
public override void Draw(Canvas label)
{
_border = new Border();
_label = label;
Rectangle x= new Rectangle ();
label.Children.Add(x);
}
internal override void AddInputs(ItemsControl inputPanel)
{
inputPanel.Items.Add(new BackgroundInput() { Title = "Background:", Box = this, Color = BackgroundColor });
}
public void redraw()
{
_label.Children.Remove(_label);
Draw(_label);
}
}
答案 0 :(得分:1)
我强烈建议您使用MVVM模式。我想你有一个想要在布局面板上绘制的对象列表(在这种情况下是画布)。
首先需要的是ViewModel。它将代表一个Rectangle实例:
public class MyRectangleViewModel : INotifyPropertyChanged
{
private Color _background;
public Color Background
{
get
{
return _background;
}
set
{
_background = value;
OnPropertyChanged();
}
}
/// <summary>
/// Occurs when [property changed].
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
请注意INotifiyPropertyChanged
界面。这将添加“WPF绑定魔法”。每次更改属性时,都会触发PropertyChanged事件。在SO和网络上有大量的教程和示例......
您可以使用ItemsControl
或类似物品,并将所有物品绑定到ItemsSource。
反正。看起来你想在代码中创建所有元素(无论出于何种原因)。所以这里有一个解决方案背后的代码#ItGivesMeTheCreeps:
/// <summary>
/// All my recangles
/// </summary>
private ObservableCollection<MyRectangleViewModel> AllMyRecangles = new ObservableCollection<MyRectangleViewModel>();
/// <summary>
/// Call this method if you add/remove objects to your list.
/// </summary>
public void RefreshObjects()
{
this.myCanvas.Children.Clear();
foreach (MyRectangleViewModel item in AllMyRecangles)
{
Rectangle newRectangle = new Rectangle();
//set the DataContext
newRectangle.DataContext = item;
//create the binding
Binding b = new Binding();
b.Source = item;
b.Path =new PropertyPath(nameof(Background));
b.Mode = BindingMode.TwoWay;
b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
//setup the binding XAML: <Rectangle Fill = {Binding Path="Background", Mode=TwoWay, UpdateSourceTrigger ="PropertyChanged" />
BindingOperations.SetBinding(newRectangle, Rectangle.FillProperty, b);
//add the rectangle to the canvas
myCanvas.Children.Add(newRectangle);
}
}