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: 对于其他在理解答案方面有问题的人,我制作了一个小图形

4

3 回答 3

2

第一种方法不起作用,因为该属性仅为注册TextBox,在另一个类中添加引用什么都不做。

第二个只是创建一个全新的字符串属性。

如果你真的想重用TextBox.TextProperty调用AddOwner就可以了。

例如

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

(请注意,此属性已注册为"Text",因此您可能应该像已经创建的那样使用您想要的名称创建一个新属性。我还建议您将元数据标志设置默认绑定双向,如果您想拥有相同的绑定行为为TextBox.Text。)

于 2012-06-11T15:04:11.280 回答
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");
        }
    }
}

用于 FilePicker 控件的 XAML:

<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 控件的 CodeBehind:

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

奇迹般有效。

于 2012-06-12T11:42:04.790 回答
0

由于我在理解HBs 的答案时遇到问题,所以我制作了一个小图,帮助我理解幕后发生的事情。这里是;

在此处输入图像描述

也许它可以帮助别人:)

于 2012-06-12T13:24:43.650 回答