Первая ошибка в том, что вы написали
ItemsSource="{Binding Source=MyProperty}"
вместо
ItemsSource="{Binding Path=MyProperty}"
или просто
ItemsSource="{Binding MyProperty}"
Установка объекта Source привязок на MyProperty
просто присваивает строковый литерал "MyProperty"
, который является IEnumerable из Chars и, следовательно, интерпретируется как таковой.
Привязка в ItemTemplate неизбежно жалуется, что не может найти свойство wWidth
для объекта типа Char
.
Но есть еще одна проблема, с которой вы сталкиваетесь. Вот правильный ответ, и, честно говоря, мне пришлось копать, чтобы получить это для вас ... У меня никогда не было этой проблемы раньше.
Во-первых, поскольку вы используете пользовательскую фигуру, ItemsControl
игнорирует пользовательский DataTemplate
и пытается нарисовать RectOverlay
, который вы указали.
Теперь, конечно, вы этого не видите, потому что вы устанавливаете только wWidth
, что не является реальной шириной рисования. Вам необходимо установить Width
, Height
, Stroke
, StrokeThickness
и т. Д. В соответствии с вашей пользовательской формой, а затем вам необходимо полностью удалить DataTemplate
из вашего XAML
.
Однако, как только вы это сделаете, вы все равно заметите, что он не тянет. Это потому, что ваш DefiningGeometry
возвращает пробел RectangleGeometry
. Это должны быть пути и т. Д., Которые вы собираетесь рисовать. (Подробнее об этом позже).
Все, что сказано, я действительно не чувствую, что вам нужна особая форма здесь; если вы действительно предоставите все требования, я предоставлю рабочую форму и покажу, как она работает. Я сделал это на своей машине здесь, но я не собираюсь публиковать этот код, потому что я думаю, что это не то, что вам действительно нужно.
Еще одна вещь, которую стоит отметить ... Если вы используете произвольную фигуру, она относится к типу DependencyObject
. Это означает, что реализация INotifyPropertyChanged
излишня. Вместо этого вы можете использовать пользовательский DependencyProperty
.
Поэтому, пожалуйста, просмотрите этот код ниже. Я изменил RectOverlay, чтобы он был больше похож на ViewModel, и я обновил MyProperty
в MainWindow
, чтобы он стал DependencyProperty
.
Вот код MainWindow
, стоящий за
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
MyProperty.Add(new RectOverlay() { wWidth = 100 });
}
public ObservableCollection<RectOverlay> MyProperty
{
get { return (ObservableCollection<RectOverlay>)GetValue(MyPropertyProperty); }
set { SetValue(MyPropertyProperty, value); }
}
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register(nameof(MyProperty), typeof(ObservableCollection<RectOverlay>), typeof(MainWindow), new PropertyMetadata(new ObservableCollection<RectOverlay>()));
}
Вот модель представления RectOverlay
public class RectOverlay : INotifyPropertyChanged
{
private double wwidth;
public double wWidth
{
get { return wwidth; }
set
{
wwidth = value;
OnPropertyChanged(nameof(wWidth));
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
Я оставил XAML
таким, каким он был у вас (за исключением удаления Source =)
Если вы уверены, что вам нужен пользовательский Shape
, тогда я тоже могу это сделать, но также предоставлю ваш вариант использования, чтобы я мог сделать это правильно, пожалуйста.
Кроме того, я удалил _timer, потому что я не использовал его для создания примера. Не забудьте добавить его обратно, если вы копируете и вставляете.