2017-06-06 18 views
0

"シンプルな"ケースで作業しています。私はDependencyPropertyを実装する新しいカスタムコントロールを作成するのが好きです。次のステップでは、両方向のプロパティを更新するためのバインディングを作成したいと思います。私はこのケースのための簡単なサンプルを構築しましたが、バインディングは動作していないようです。私はFrameworkPropertyMetadataを使用してDPControlのプロパティを更新する方法を見つけましたが、OnPropertyChangedイベントを使用することも良い考えであるかどうかはわかりません。 HEREバインディングの依存関係プロパティを作成する方法

は私のサンプルプロジェクトです:

私のコントロールは、単にラベル

<UserControl x:Class="WPF_MVVM_ListBoxMultiSelection.DPControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:WPF_MVVM_ListBoxMultiSelection" 
      mc:Ignorable="d" Height="84.062" Width="159.641"> 
    <Grid Margin="0,0,229,268"> 
     <Label Content="TEST" x:Name="label" Margin="0,0,-221,-102"/> 
    </Grid> 
</UserControl> 

とカスタム依存関係プロパティを実装が含まれています。現時点では、FramePropertyMetadataのPropertyChangedメソッドも実装しており、このメソッドではラベルのコンテンツを設定していますが、両方向で動作させるのが好きです。

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

    public string MyCustomLabelContent 
    { 
     get { return (string)GetValue(MyCustomLabelContentProperty);} 
     set 
     { 
      SetValue(MyCustomLabelContentProperty, value); 
     } 
    } 

    private static void OnMyCustomLabelContentPropertyChanged(DependencyObject source, 
    DependencyPropertyChangedEventArgs e) 
    { 
     DPControl control = (DPControl)source; 
     control.label.Content = e.NewValue; 
    } 

    public static readonly DependencyProperty MyCustomLabelContentProperty = DependencyProperty.Register(
      "MyCustomLabelContent", 
      typeof(string), 
      typeof(DPControl), 
      new FrameworkPropertyMetadata(null, 
       OnMyCustomLabelContentPropertyChanged 
     ) 
     ); 

Iは、ウィンドウ内単にこのコントロールを使用する:

<local:DPControl MyCustomLabelContent="{Binding MyLabelContent, Mode=TwoWay}" Margin="72,201,286,34"/> 

MyLabelContentもINotifyPropertyChangedインターフェイスを実装しているビューモデルにおける特性です。

public class ViewModel_MainWindow:NotifyPropertyChanged 
{ 

    private string _myLabelContent; 

    public string MyLabelContent 
    { 
     get { return _myLabelContent; } 
     set { _myLabelContent = value; 
      RaisePropertyChanged(); 
     } 
    }... 

どのように私はそれを働かせることができます:カスタムプロパティの新しいコントロールでバインディング機能を使用します。ユーザーコントロールで

答えて

2

<Label 
    Content="{Binding MyCustomLabelContent, RelativeSource={RelativeSource AncestorType=UserControl}}" 
    x:Name="label" Margin="0,0,-221,-102"/> 

そして、そのプロパティ変更コールバックを取り除きます。必要なのはバインディングだけです。

は、私はそれがデフォルトで依存関係プロパティの双方向を作るために両方向

で仕事を取得したい:

public static readonly DependencyProperty MyCustomLabelContentProperty = 
    DependencyProperty.Register(
     "MyCustomLabelContent", 
     typeof(string), 
     typeof(DPControl), 
     new FrameworkPropertyMetadata(null, 
      FrameworkPropertyMetadataOptions.BindsTwoWayByDefault) 
    ); 

私は不必要なプロパティの変更ハンドラを省略しました。

Label.Contentは独自の値を生成できないため、現在は双方向であることは有益ではありません。あなたのユーザーコントロールは、その分離コードで値を設定したい場合は、それは簡単です:

MyCustomLabelContent = "Some arbitrary value"; 

あなたは、私がお見せしたように、それがユーザーコントロールXAMLでラベルなどに結合しているのviewmodelプロパティを更新するバインディングなかった場合UserControlの依存関係プロパティ

あなたはXAMLはそれを設定したい場合は、この、

最後にする必要があります

Margin="0,0,-221,-102" 

レイアウトを行うには良い方法ではありません。 Grid,StackPanelなどのWPFレイアウトははるかに簡単で堅牢です。

+0

ありがとう、これは単純なケースでは機能しますが、ItemsSelectedを取得するためのリストボックスのwrapper-usercontrolのように実装したいのですが、動作しません。この場合のヒント? – Kinimod

+0

@Kinimod ItemsSelectedは痛みです:あなたはそれを縛ることはできません。またコレクションなので、変更通知を処理する必要があります。それは別の質問です。 –

+0

あなたはそれが痛みです。バインディングのSelectedItemsリストを持つリストボックスのような、リストを扱う他のサードパーティコントロールに対する提案はありますか? – Kinimod

関連する問題