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の変換方法を理解できません。クレメンスへ
アイテムコンテナ(およびそのすべての子)のデータコンテキストすでに自動的に適切に設定されていますデータ項目オブジェクト。したがって、 'ClassObject'を' {Binding} 'に設定することは完全に冗長なようです。あなたのClassShapeViewのコンストラクタから 'this.DataContext = new ClassShapeViewModel();'を削除するだけで、DataContextを継承し、UserControlを継承したDataContextのClassObjectインスタンスに対して直接操作させることができます。 – Clemens
これは非常に珍しい方法です。通常、ビューモデル間の関係と接続は、ビューモデル自体によって設定されます。この見解は、そこに見つかったものを反映しているだけです。なぜClassObjectのプロパティをShapeViewのプロパティにバインドしないのですか?とにかく、あなたのDataTemplateでは、 '{Binding}'はDataContextです - ClassObjectです。 {Binding RelativeSource = {RelativeSource Self}} 'が必要です。スタイル・セッターではなく、ShapeViewで直接試してみます。 –
つまり、UserControlが独自のビューモデルを使用する必要はありません。特に、継承されたDataContextで操作する必要があるシナリオで使用されるときは、独自のビューモデルインスタンスを作成しないでください。 [この回答](http://stackoverflow.com/a/37475541/1136211)も参照してください。 – Clemens