我想创建自己的UserControl(让我们称之为“RectAtCoordinates”),它的工作方式与Canvas类似,但它应该:
- (x,y)整数坐标的存储集合
- 在画布上为每个(x,y)对绘制矩形(具有任意选择的大小和填充)。 (x,y)指定矩形的位置。
首先,我创建了简单的坐标类:
class Coordinates : DependencyObject
{
public static readonly DependencyProperty XProperty =
DependencyProperty.Register("X", typeof(int), typeof(Coordinates));
public static readonly DependencyProperty YProperty =
DependencyProperty.Register("Y", typeof(int), typeof(Coordinates));
public int X
{
get { return (int)GetValue(XProperty); }
set { SetValue(XProperty, value); }
}
public int Y
{
get { return (int)GetValue(YProperty); }
set { SetValue(YProperty, value); }
}
public Coordinates(int x, int y)
{
this.X = x;
this.Y = y;
}
}
这是我的 RectAtCoordinates UserControl (.xaml):
<UserControl x:Class="RectAtPoint.RectAtCoordinates"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<ItemsControl ItemsSource="{Binding Path=Coos, Mode=OneWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Width="300" Height="300" Background="White"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Fill="Black" Width="50" Height="50"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding Path=X}" />
<Setter Property="Canvas.Top" Value="{Binding Path=Y}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</UserControl>
最后代码支持RectAtCoordinates :
public partial class RectAtCoordinates : UserControl
{
public static readonly DependencyProperty CoosProperty =
DependencyProperty.Register("Coos", typeof(Coordinates), typeof(RectAtCoordinates));
private ObservableCollection<Coordinates> Coos
{
get { return (ObservableCollection<Coordinates>)GetValue(CoosProperty); }
set { SetValue(CoosProperty, value); }
}
public RectAtCoordinates()
{
InitializeComponent();
Coos = new ObservableCollection<Coordinates>();
}
public void AddRectangleAtPosition(int x, int y)
{
Coos.Add(new Coordinates(x, y));
}
}
然而,在构建我的项目后它崩溃了。我得到了CLR20r3问题。经过进一步检查后,我将RectAtCoordinates构造函数更改为:
public RectAtCoordinates()
{
InitializeComponent();
try
{
Coos = new ObservableCollection<Coordinates>();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
得到了这个错误:
System.ArgumentException: 'System.Collections.ObjectModel.ObservableCollection`1 [RectAtPoint.Coordinates]' 对于属性'Coos'而言,它不是有效值。
在 System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, 对象值,PropertyMetadata元数据,布尔值 coerceWithDeferredReference,Boolean coerceWithCurrentValue, OperationType operationType,Boolean isInternal)
在System.Windows.DependencyObject.SetValue(DependencyProperty dp, 对象值)
在RectAtPoint.RectAtCoordinates.set_Coos(ObservableCollection`1 c)中的值:... \ RectAtCoordinates.xaml.cs:第28行
在RectAtPoint.RectAtCoordinates..ctor()中 c:... \ RectAtCoordinates.xaml.cs:第36行
我是新手考虑WPF,绑定和依赖属性,所以请考虑到我可能犯了一些基本错误。我发现了许多类似的问题,但我无法完全理解解决方案,因此正确应用它们。
答案 0 :(得分:3)
我认为你的问题就在这里:
public static readonly DependencyProperty CoosProperty =
DependencyProperty.Register("Coos", typeof(Coordinates), typeof(RectAtCoordinates));
应该是:
public static readonly DependencyProperty CoosProperty =
DependencyProperty.Register("Coos", typeof(ObservableCollection<Coordinates>), typeof(RectAtCoordinates));
试一试:)
===编辑===坐标。
我认为你可以这样做:
public void AddRectangleAtPosition(int x, int y)
{
Coos.Add(new Coordinates(x, y));
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Coos"));
}
}
然后你的班级应该:
public partial class RectAtCoordinates : UserControl, INotifyPropertyChanged
之后,您可以拥有像我通常拥有的NotifyPropertyChanged这样的区域:
#region notifypropertychanged region
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField<T>(ref T field, T value, string propertyName)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
#endregion
}
试一试:)
答案 1 :(得分:-3)
我终于找到了一个解决方案:未正确设置数据上下文。 我不得不添加
this.DataContext = this;
到UserControl的构造函数或添加:
DataContext="{Binding RelativeSource={RelativeSource Self}}"
到UserControl的xaml定义。