2012-06-11 151 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 –