У меня возникла проблема с Attached Properties в MVVM. Я создаю приложение WPF C#.MVVM Прикрепленная модель объекта недвижимости
Я заполняю ObserverableCollection специальными классами класса ClassObject. И из этой коллекции я создаю ClassShapeViews на холсте. Этим ClassShapeViews нужна ссылка на объект ClassObject для отображения правильной информации.
Чтобы передать ссылку ClassObject я привязки к AttachedProperty в XAML как это:
<ItemsControl ItemsSource="{Binding ClassObjectList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas x:Name="canvas" Background="White" AllowDrop="True"
DragEnter="canvas_DragEnter"
DragOver="canvas_DragOver"
Drop="canvas_Drop"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<!-- This part doesn't work-->
<shape:ClassShapeView>
<Style TargetType="shape:ClassShapeView">
<Setter Property="shape:ClassShapeView.ClassObject" Value="{Binding}"/>
</Style>
</shape:ClassShapeView>
<Label Content="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
В Кодексе позади от ClassShapeView Я handeling в DependencyProperty:
public partial class ClassShapeView : UserControl
{
protected ClassShapeViewModel viewModel { get { return DataContext as ClassShapeViewModel; } }
public ClassShapeView()
{
InitializeComponent();
this.DataContext = new ClassShapeViewModel();
}
public static readonly DependencyProperty ClassObjectProperty =
DependencyProperty.RegisterAttached("ClassObject", typeof(ClassObject), typeof(ClassShapeView), new PropertyMetadata(default(ClassObject)));
public static void SetClassObject(UIElement element, ClassObject value)
{
element.SetValue(ClassObjectProperty, value);
}
public static ClassObject GetClassObject(UIElement element)
{
return (ClassObject)element.GetValue(ClassObjectProperty);
}
public ClassObject MyClassObject
{
get { return viewModel.ClassObject; }
set { viewModel.ClassObject = value; }
}
}
После получения ссылки на ClassObject я хочу отправить эту ссылку в прикрепленный ViewModel с свойством MyClassObject. Данные в ClassShapeView привязаны к ViewModel.
Я просто не могу понять, как преобразовать CodeObject Reference форму CodeBehind в ViewModel.
DataContext контейнера для элемента (и все его дети) уже автоматически устанавливается в соответствующее объект элемента данных. Поэтому установка 'ClassObject' в' {Binding} 'кажется полностью избыточной. Просто удалите 'this.DataContext = new ClassShapeViewModel();' из конструктора ClassShapeView, чтобы включить наследование DataContext, и позволить UserControl напрямую работать с экземпляром ClassObject в унаследованном DataContext. – Clemens
Это очень необычный способ сделать что-то. Обычно отношения и связи между моделями представлений устанавливаются самими моделями представлений. Взгляд просто отражает то, что он находит там. Почему бы не привязать свойства ClassObject к свойствам ShapeView? Во всяком случае, в вашем DataTemplate, '{Binding}' является DataContext - ClassObject. Вы хотите '{Binding RelativeSource = {RelativeSource Self}}'. Я бы попробовал это прямо в ShapeView, а не в стиле setter. –
Другими словами, нет необходимости, чтобы UserControl использовал свою собственную модель представления. Тем не менее, он никогда не должен создавать свой собственный экземпляр модели представления, когда он используется в сценарии, где он должен работать с унаследованным DataContext. См. Также [этот ответ] (http://stackoverflow.com/a/37475541/1136211). – Clemens