2016-06-16 2 views
-1

У меня возникла проблема с 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.

+1

DataContext контейнера для элемента (и все его дети) уже автоматически устанавливается в соответствующее объект элемента данных. Поэтому установка 'ClassObject' в' {Binding} 'кажется полностью избыточной. Просто удалите 'this.DataContext = new ClassShapeViewModel();' из конструктора ClassShapeView, чтобы включить наследование DataContext, и позволить UserControl напрямую работать с экземпляром ClassObject в унаследованном DataContext. – Clemens

+0

Это очень необычный способ сделать что-то. Обычно отношения и связи между моделями представлений устанавливаются самими моделями представлений. Взгляд просто отражает то, что он находит там. Почему бы не привязать свойства ClassObject к свойствам ShapeView? Во всяком случае, в вашем DataTemplate, '{Binding}' является DataContext - ClassObject. Вы хотите '{Binding RelativeSource = {RelativeSource Self}}'. Я бы попробовал это прямо в ShapeView, а не в стиле setter. –

+2

Другими словами, нет необходимости, чтобы UserControl использовал свою собственную модель представления. Тем не менее, он никогда не должен создавать свой собственный экземпляр модели представления, когда он используется в сценарии, где он должен работать с унаследованным DataContext. См. Также [этот ответ] (http://stackoverflow.com/a/37475541/1136211). – Clemens

ответ

0

Благодаря Clemens я есть ответ

«, когда свойство ItemsSource в ItemsControl в привязывается к коллекции экземпляров ClassObject (как я полагаю, ваш ClassObjectList), то DataContext каждого контейнера элемента (например, ContentPresenter), устанавливается в соответствующий элемент из коллекции. Этот DataContext наследуется в ItemTemplate, так что элементы управления внутри DataTemplate (например, ваш UserControl) уже получают правильный элемент ClassObject в качестве своего DataContext. "

Так что мой 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> 
        <shape:ClassShapeView/> 
       </StackPanel> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 

И мой взгляд выглядит следующим образом:

public partial class ClassShapeView : UserControl 
{ 
    public ClassShapeView() 
    { 
     InitializeComponent();  
    } 
}