2017-02-02 7 views
1

私は、ビューモデルでバインドされた依存プロパティを少し実験することに決めました。今、私は内容を期待Custom DependencyPropertyがElementNameにバインドしない

public class ViewModel2 : DependencyObject 
{ 
    public string BoundString 
    { 
     get { return (string)GetValue(BoundStringProperty); } 
     set { SetValue(BoundStringProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for BoundString. 
    public static readonly DependencyProperty BoundStringProperty = 
     DependencyProperty.Register("BoundString", typeof(string), typeof(ViewModel2), 
      new FrameworkPropertyMetadata(default(string), 
       FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 
} 

<Window x:Class="MVVM_Test.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:MVVM_Test" 
     xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase" 
     xmlns:sys="clr-namespace:System;assembly=mscorlib" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition /> 
      <RowDefinition /> 
     </Grid.RowDefinitions> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition /> 
      <ColumnDefinition /> 
     </Grid.ColumnDefinitions> 
     <ListBox Margin="6" Grid.RowSpan="2" Name="PART_LISTBOX"> 
      <sys:String>String 1</sys:String> 
      <sys:String>String 2</sys:String> 
      <sys:String>String 3</sys:String> 
     </ListBox> 
     <StackPanel Name="PART_spViewModel2" Grid.Column="1" Grid.Row="1"> 
      <StackPanel.DataContext> 
       <local:ViewModel2 BoundString="{Binding ElementName=PART_LISTBOX, 
            Path=SelectedItem, 
            diag:PresentationTraceSources.TraceLevel=High}" /> 
      </StackPanel.DataContext> 
      <TextBox Margin="6" Text="{Binding BoundString}" /> 
     </StackPanel> 
    </Grid> 
</Window> 

を、簡単なビューモデルオブジェクトによってバックアップ:そのために私はMainWindow.xamlからなる、簡単なテストプロジェクトを設定していますListBox内で何かを選択すると、変更するテキストボックス。私が行う場合

System.Windows.Data Warning: 67 : BindingExpression (hash=61931053): Resolving source (last chance)

System.Windows.Data Warning: 69 : BindingExpression (hash=61931053): Framework mentor not found

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=SelectedItem; DataItem=null; target element is 'ViewModel2' (HashCode=64815892); target property is 'BoundString' (type 'String')

:それはこの点をヒットするまで

System.Windows.Data Warning: 56 : Created BindingExpression (hash=61931053) for Binding (hash=40205895)

System.Windows.Data Warning: 58 : Path: 'SelectedItem'

System.Windows.Data Warning: 60 : BindingExpression (hash=61931053): Default mode resolved to TwoWay

System.Windows.Data Warning: 61 : BindingExpression (hash=61931053): Default update trigger resolved to PropertyChanged

System.Windows.Data Warning: 62 : BindingExpression (hash=61931053): Attach to MVVM_Test.ViewModel2.BoundString (hash=64815892)

System.Windows.Data Warning: 64 : BindingExpression (hash=61931053): Use Framework mentor

System.Windows.Data Warning: 67 : BindingExpression (hash=61931053): Resolving source

System.Windows.Data Warning: 69 : BindingExpression (hash=61931053): Framework mentor not found

System.Windows.Data Warning: 65 : BindingExpression (hash=61931053): Resolve source deferred

繰延検索が少し上で行く:私はプログラムを実行するときしかし、それはそうListBoxのは、データバインディングによって発見することができません他の方法で結合する、例えばListBox.SelectedItemプロパティからViewModelに向かって動作します。

<ListBox Margin="6" Grid.RowSpan="2" Name="PART_LISTBOX" 
     SelectedItem="{Binding ElementName=PART_spViewModel2, 
     Path=DataContext.BoundString}"> 

私はDependencyPropertyを正しく設定していないと思いますが、正確にどこでミスを犯しましたか?

+0

:あなたは、この詳細については、次の質問を参照することができます。ビューモデル*は* DataContextです。つまり、*ソース*プロパティを定義します。ビジュアルツリーには追加されないため、BoundString依存関係プロパティをListBoxのSelectedItemプロパティのターゲットプロパティとして使用することはできません。 – mm8

+0

したがって、プロパティにバインドするには、オブジェクトがビジュアルツリーの一部である必要があります.BindingExpressionは、参照された実際のFrameworkElementを正しく識別するために参照の親を実際に探しているため、DataContextその親を割り当てられることはありませんか?これは、最初にビューモデルに 'DependencyProperty'を必要としないことを意味し、最初にビューモデルの' NotifyPropertyChanged'プロパティで単に行うことができますか? – Adwaenyth

+0

はい、ビューモデルには依存関係のプロパティは必要ありません。私の答えを見てください。 – mm8

答えて

1

ビュー内のターゲットプロパティをDataContextのソースプロパティにバインドします。ビューモデルはDataContextです。つまり、ソースプロパティを定義します。ビジュアルツリーには追加されないため、BoundString依存関係プロパティをListBoxのSelectedItemプロパティのターゲットプロパティとして使用することはできません。

一般に、ビューモデルのソースプロパティはCLRプロパティとして定義されますが、ターゲットプロパティ、つまり何かをバインドするプロパティは依存プロパティとして定義する必要があります。あなたはDataContextのの*ソース*プロパティにビューで*目標*プロパティをバインド

Can somone give example of Dependency Property in ViewModel

INotifyPropertyChanged vs. DependencyProperty in ViewModel

関連する問題