我正在尝试创建一个简单的依赖属性代理。我制作了一个自定义控件,它是一个文件选择器,由一个文本框(名称:"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
答案 0 :(得分:2)
第一种方法不起作用,因为该属性仅为TextBox
注册,在另一个类中添加引用不起任何作用。
第二个只是创建一个全新的字符串属性。
如果您真的想在其上重复使用TextBox.TextProperty
来电AddOwner
。
e.g。
public static readonly DependencyProperty SelectedFilePathProperty =
TextBox.TextProperty.AddOwner(typeof(FilePicker));
(请注意,此属性已注册为"Text"
,因此您可能应该只创建一个具有所需名称的新属性。我还建议set metadata flags到{{3如果你想拥有与TextBox.Text
相同的绑定行为。)
答案 1 :(得分:1)
这个解决方案有点棘手但有效。
鉴于此用户控制:
<Grid>
<StackPanel>
<WpfApplication1:FilePicker SelectedFilePath ="{Binding MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="{Binding MyProperty}" />
</StackPanel>
</Grid>
它的viewmodel:
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>
CodePehind for 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); }
}
}
像魅力一样。
答案 2 :(得分:0)