2017-06-06 57 views
0

我正在研究一個「簡單」的案例。我喜歡創建一個實現了DependencyProperty的新自定義控件。在下一步中,我喜歡創建一個綁定來更新兩個方向的屬性。我爲這種情況建立了一個簡單的例子,但綁定似乎不起作用。我找到了使用FrameworkPropertyMetadata更新DPControl屬性的方法,但我不知道使用OnPropertyChanged事件是否也是個好主意。如何創建綁定的依賴項屬性

這裏是我的樣本項目:

我的控件包含一個簡單的標籤

<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方法,並在該方法中設置了標籤的內容,但是我喜歡使它在兩個方向上都能正常工作。

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

MyLabelContent是在視圖模型,這也實現INotifyPropertyChanged接口的屬性:

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

我簡單地在窗口中通過使用該控制。

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標籤以及綁定到視圖模型屬性UserControl的依賴項屬性。

如果你想在XAML來設置它,你需要

最後,這樣的:

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

是不是做佈局的好方法。 WPF佈局與Grid,StackPanel等更容易和更強大。

+0

謝謝,這個工程的簡單情況,但現在我想實現類似於包裝,用戶控件的列表框用於獲取ItemsSelected,但它不工作。有關這種情況的任何提示? – Kinimod

+0

@Kinimod ItemsSelected是一種痛苦:你無法綁定它。它也是一個集合,所以你必須處理更改通知。這是另一個問題。 –

+0

你是對的,這是一個痛苦。對於另一個第三方控件處理列表的任何建議,如列表框,其中有一個SelectedItems列表進行綁定? – Kinimod