2012-06-11 65 views
6

我想創建一個簡單的依賴項屬性代理。我製作了一個自定義控件,它是一個文件選擇器,由文本框(名稱:"TextBox_FilePath")和一個顯示打開文件對話框的按鈕組成。創建一個依賴項屬性的代理

由於我正在製作可重複使用的控件,我希望它具有"SelectedFilePath"屬性。由於Text屬性似乎是完美的我的控制是"SelectedFilePath"屬性,我只想代理這些依賴屬性。

我提出的第一種方法是:

public static readonly DependencyProperty SelectedFilePathProperty = TextBox.TextProperty; 

public string SelectedFilePath 
{ 
    get { return (string) this.TextBox_FilePath.GetValue(SelectedFilePathProperty); } 
    set { this.TextBox_FilePath.SetValue(SelectedFilePathProperty, value); } 
} 

其工作,但扔試圖綁定到該屬性時異常。然後我脫掉了:

public static readonly DependencyProperty SelectedFilePathProperty = 
    DependencyProperty.Register("SelectedFilePath", typeof (string), typeof (FilePicker), new PropertyMetadata(default(string))); 

public string SelectedFilePath 
{ 
    get { return (string) this.TextBox_FilePath.GetValue(SelectedFilePathProperty); } 
    set { this.TextBox_FilePath.SetValue(SelectedFilePathProperty, value); } 
} 

哪個工作,但我不知道爲什麼?!我在哪裏指定我想要文本框的text屬性?

我錯過了什麼,只是代理出來的依賴屬性?

編輯:AddOwner的解決方案不工作過,它拋出一個EXCETION說:「結合只能在一個依賴屬性應用」。代碼:

public static readonly DependencyProperty SelectedFilePathProperty = 
    TextBox.TextProperty.AddOwner(typeof(FilePicker)); 

public string SelectedFilePath 
{ 
    get { return (string)this.TextBox_FilePath.GetValue(SelectedFilePathProperty); } 
    set { this.TextBox_FilePath.SetValue(SelectedFilePathProperty, value); } 
} 

我不明白?

EDIT2: 對於大家理解別人的答案有問題,我做了a little graphic

回答

3

第一種方法不起作用,因爲該屬性是只爲TextBox註冊,增加在另一參考班級什麼都不做。

第二個只是創建一個全新的字符串屬性。

如果您真的想重新使用TextBox.TextProperty請致電AddOwner就可以了。

例如

public static readonly DependencyProperty SelectedFilePathProperty = 
    TextBox.TextProperty.AddOwner(typeof(FilePicker)); 

(注意,這個屬性被註冊爲"Text",所以你可能,如果你想擁有的應該只是創建一個名爲您想爲你做了。我也建議set metadata flagsbind two-way by default一個新的屬性與TextBox.Text相同的結合行爲。)

+0

請看看我的編輯:) – GameScripting

+0

*正如我所說的*,它的名稱爲「文本」中註冊,可以因此只有綁定到一個所謂的財產'Text',你創建的'SelectedFilePath'屬性只是爲了方便你的命令式代碼的一個包裝,綁定永遠不會使用它。如果你想要一個不同的名字,請註冊你自己的房產 –

+0

願你如此善良,並提供一個例子或提供任何參考如何做到這一點? – GameScripting

1

該解決方案有點棘手,但有效。

鑑於這種用戶控件:

<Grid> 
    <StackPanel> 
     <WpfApplication1:FilePicker SelectedFilePath ="{Binding MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
     <TextBlock Text="{Binding MyProperty}" /> 
    </StackPanel> 
</Grid> 

而其視圖模型:

public class MainWindowViewModel : INotifyPropertyChanged 
{ 
    #region Implementation of INotifyPropertyChanged 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void OnPropertyChanged(string e) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) handler(this, new PropertyChangedEventArgs(e)); 
    } 

    #endregion 

    private string _myProperty; 
    public string MyProperty 
    { 
     get { return _myProperty; } 
     set 
     { 
      _myProperty = value; 
      OnPropertyChanged("MyProperty"); 
     } 
    } 
} 

XAML爲FilePicker控制:

<Grid> 
    <TextBox x:Name="TextBox_FilePath" DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type WpfApplication1:FilePicker}}}" Text="{Binding SelectedFilePath, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
</Grid> 

代碼隱藏於FilePicker控制:

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

    /* private PROXY DP*/ 
    private static readonly DependencyProperty TextProperty = 
     TextBox.TextProperty.AddOwner(typeof(FilePicker)); 

    /* public DP that will fire getter/setter for private DP */ 
    public static readonly DependencyProperty SelectedFilePathProperty = 
     DependencyProperty.Register("SelectedFilePath", typeof(string), typeof(FilePicker), new PropertyMetadata(default(string))); 

    public string SelectedFilePath 
    { 
     get { return (string)GetValue(TextProperty); } 
     set { SetValue(TextProperty, value); } 
    } 
} 

工程就像一個魅力。

+0

完整的Gist可以在這裏找到:https://gist.github.com/2917066 –

+0

非常感謝你,沒有你的榜樣我不會得到它的工作! – GameScripting

0

由於我對理解H.B.s answer有一定的理解,所以我做了一個小小的圖形,這有助於我理解發生了什麼。這裏是;

enter image description here

也許它可以幫助別人:)

+0

現在我得到了你沒有得到的東西:P –