2016-06-16 6 views
-1

MVVMの添付プロパティでこの問題が発生しました。私はC#WPFアプリケーションを構築しています。MVVM接続プロパティビューモデル

ObserverableCollectionにClassObject型のカスタムクラスを設定しています。このコレクションからは、キャンバスにClassShapeViewを作成しています。これらのClassShapeViewは、正しい情報を表示するためにClassObjectへの参照を必要とします。私がしたDependencyPropertyをhandelingてるClassShapeViewの背後にあるコードで

<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> 

私はこのようなXAMLでAttachedPropertyに結合していClassObjectの参照を渡す

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 Referenceを受け取った後、このリファレンスをMyClassObjectプロパティを持つ添付ViewModelに送信します。 ClassShapeViewのデータはViewModelにバインドされています。

私は、CodeBehindからClassModeへのClassObject Referenceの変換方法を理解できません。クレメンスへ

+1

アイテムコンテナ(およびそのすべての子)のデータコンテキストすでに自動的に適切に設定されていますデータ項目オブジェクト。したがって、 'ClassObject'を' {Binding} 'に設定することは完全に冗長なようです。あなたのClassShapeViewのコンストラクタから 'this.DataContext = new ClassShapeViewModel();'を削除するだけで、DataContextを継承し、UserControlを継承したDataContextのClassObjectインスタンスに対して直接操作させることができます。 – Clemens

+0

これは非常に珍しい方法です。通常、ビューモデル間の関係と接続は、ビューモデル自体によって設定されます。この見解は、そこに見つかったものを反映しているだけです。なぜClassObjectのプロパティをShapeViewのプロパティにバインドしないのですか?とにかく、あなたのDataTemplateでは、 '{Binding}'はDataContextです - ClassObjectです。 {Binding RelativeSource = {RelativeSource Self}} 'が必要です。スタイル・セッターではなく、ShapeViewで直接試してみます。 –

+2

つまり、UserControlが独自のビューモデルを使用する必要はありません。特に、継承されたDataContextで操作する必要があるシナリオで使用されるときは、独自のビューモデルインスタンスを作成しないでください。 [この回答](http://stackoverflow.com/a/37475541/1136211)も参照してください。 – Clemens

答えて

0

感謝のItemsControlのItemsSourceプロパティは、(私はあなたのClassObjectListであると仮定するものとして)ClassObjectインスタンスのコレクションにバインドされたとき、私は、各項目のコンテナのその後のDataContext(例えばAのContentPresenter、」答え

を持っています)は、コレクションの各要素に設定されます。このDataContextはItemTemplateに継承され、DataTemplate内のコントロール(UserControlなど)がDataObjectとして正しいClassObject要素を取得します。

だから私の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();  
    } 
} 
関連する問題