您的<StackPanel>s 是某个 UserControl 的一部分吗?如果不是,你为什么使用DependencyProperty?
你的实现也很差。
让我们假设这不是自定义控件的一部分(纠正我——如果我错了,我会重写解决方案)
所以你有一个 ViewModel 并且你想将一些属性连接到它。你真的不需要实现 DependencyProperty 来做你想做的事,但我会以你的方式实现它来娱乐你。
这是一个具有 1(一个)属性的示例 ViewModel
using Windows.UI.Xaml;
using System.ComponentModel;
// very simple view model
class MyViewModel : DependencyObject, INotifyPropertyChanged
{
// implement INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
// register
public static DependencyProperty FooterTitleProperty = DependencyProperty.Register("FooterTitle", typeof(string), typeof(MyViewModel),
new PropertyMetadata(string.Empty, OnFooterTitlePropertyChanged));
// the actual property
public string FooterTitle
{
get { return (string) GetValue(FooterTitleProperty); }
set
{
SetValue(FooterTitleProperty, value);
}
}
// this will fire when the property gets change
// it will call the OnPropertyChanged to notify the UI element to update its layout
private static void OnFooterTitlePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
MyViewModel mvm = dependencyObject as MyViewModel;
mvm.OnPropertyChanged("FooterTitle");
}
}
为了测试代码,我们将制作一个非常简单的 XAML 表单
<Grid x:Name="ContentPanel">
<StackPanel>
<TextBlock x:Name="tb" Text="{Binding FooterTitle}" FontSize="48"></TextBlock>
<Button Content="Test Property" Click="Button_Click_1"></Button>
</StackPanel>
</Grid>
当您单击按钮时,我们将更改文本框的文本
public sealed partial class MainPage : Page
{
// create the view model
MyViewModel vm = new MyViewModel();
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
// set the text we initial want to display
vm.FooterTitle = "default text";
// set the DataContext of the textbox to the ViewModel
tb.DataContext = vm;
}
// after the button is click we change the TextBox's Text
private void Button_Click_1(object sender, RoutedEventArgs e)
{
// change the text
vm.FooterTitle = "Test Property Has Changed.";
// what happens is the Setter of the Property is called first
// after that happens it launches the `OnFooterTitlePropertyChanged` event
// that we hook up with the Register function.
// `OnFooterTitlePropertyChanged` launches the INotifyPropertyChanged event
// then finally the TextBox will updates it's layout
}
}
此时你可以猜到你真的不需要 DependencyProperty 并说为什么我不能直接在 Setter 中启动 INotifyPropertyChanged 呢?好吧,你可以,这可能是首选方法。
如果所有这些都是 UserControl 的一部分,那么我可以看到使用 DependencyProperty 然后在 OnFooterTitlePropertyChanged 事件中您可以设置
name_of_textbox.Text = FooterTitle;