如何在UserControl中使用bound XAML 属性?
How to use bound XAML property in UserControl?
我有自己的UserControl
<local:MyUserControl MyProperty="{Binding myString}"/>
并且我将 myString
绑定到它。现在我想在我的 UserControl
中使用它。我在 UserControl
中定义了 DependencyProperty
:
public string MyProperty
{
get { return (string)GetValue(MyPropertyProperty); }
set
{
Debug.WriteLine(value);//writes nothing, null
SetValue(MyPropertyProperty, value);
}
}
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("MyProperty", typeof(string), typeof(MyUserControl), new PropertyMetadata(null));
我做错了什么?我想用这个字符串做一些事情。但它始终为空。
如果您使用 c# 命名约定 - 字段是驼峰式 - 您将这些东西绑定到一个字段 (myString)。它不工作。您必须绑定到 属性(Pascalcase - 获取;设置;...等)。
在这种情况下,您的输出 window.
中存在绑定错误
依赖项 属性 的默认设置是 OneWay 绑定,这意味着如果用户控件更改字符串,它不会反映在 DataContext 中。
将绑定更改为 TwoWay
<local:MyUserControl MyProperty="{Binding myString, Mode=TwoWay}"/>
或将您的 DependencyProp 更改为 TwoWay 模式:
DependencyProperty.Register("MyString", typeof(string), typeof(MyUserControl), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
Debug.WriteLine(value);
什么都不写,不是因为值是null
。依赖项 属性 的 getter 和 setter 不能保证是 运行,而使用 {Binding}
时,你的 属性 的 setter =] 没有被调用。您可以在 setter 中添加一个断点来测试它。
请注意 Custom dependency properties 中的以下注意事项:
In all but exceptional circumstances, your wrapper implementations should perform only the GetValue and SetValue operations. Otherwise, you'll get different behavior when your property is set via XAML versus when it is set via code. For efficiency, the XAML parser bypasses wrappers when setting dependency properties; whenever possible, it uses the registry of dependency properties.
您可以在对 DependencyProperty.Register
的原始调用中添加一个 属性 更改的处理程序,而不是在 属性 的 setter 中做出反应,并且在此处理程序中,您可以对新值采取行动。例如:
public string MyProperty
{
get { return (string)GetValue(MyPropertyProperty); }
set
{
SetValue(MyPropertyProperty, value);
}
}
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("MyProperty", typeof(string), typeof(MyUserControl), new PropertyMetadata(null, OnPropertyChanged));
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if ((string)e.NewValue != (string)e.OldValue)
{
Debug.WriteLine(e.NewValue);
}
}
如果你想在你的UserControl
中使用绑定字符串,你可以使用UserControl
的MyProperty
。例如:
在你的 UserControl
:
<UserControl Name="root" ...>
<StackPanel>
<TextBlock Text="{Binding MyProperty, ElementName=root}" />
</StackPanel>
</UserControl>
然后当你使用<local:MyUserControl MyProperty="{Binding myString}"/>
时,你的UserControl
会显示myString
的值。
我有自己的UserControl
<local:MyUserControl MyProperty="{Binding myString}"/>
并且我将 myString
绑定到它。现在我想在我的 UserControl
中使用它。我在 UserControl
中定义了 DependencyProperty
:
public string MyProperty
{
get { return (string)GetValue(MyPropertyProperty); }
set
{
Debug.WriteLine(value);//writes nothing, null
SetValue(MyPropertyProperty, value);
}
}
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("MyProperty", typeof(string), typeof(MyUserControl), new PropertyMetadata(null));
我做错了什么?我想用这个字符串做一些事情。但它始终为空。
如果您使用 c# 命名约定 - 字段是驼峰式 - 您将这些东西绑定到一个字段 (myString)。它不工作。您必须绑定到 属性(Pascalcase - 获取;设置;...等)。 在这种情况下,您的输出 window.
中存在绑定错误依赖项 属性 的默认设置是 OneWay 绑定,这意味着如果用户控件更改字符串,它不会反映在 DataContext 中。
将绑定更改为 TwoWay
<local:MyUserControl MyProperty="{Binding myString, Mode=TwoWay}"/>
或将您的 DependencyProp 更改为 TwoWay 模式:
DependencyProperty.Register("MyString", typeof(string), typeof(MyUserControl), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
Debug.WriteLine(value);
什么都不写,不是因为值是null
。依赖项 属性 的 getter 和 setter 不能保证是 运行,而使用 {Binding}
时,你的 属性 的 setter =] 没有被调用。您可以在 setter 中添加一个断点来测试它。
请注意 Custom dependency properties 中的以下注意事项:
In all but exceptional circumstances, your wrapper implementations should perform only the GetValue and SetValue operations. Otherwise, you'll get different behavior when your property is set via XAML versus when it is set via code. For efficiency, the XAML parser bypasses wrappers when setting dependency properties; whenever possible, it uses the registry of dependency properties.
您可以在对 DependencyProperty.Register
的原始调用中添加一个 属性 更改的处理程序,而不是在 属性 的 setter 中做出反应,并且在此处理程序中,您可以对新值采取行动。例如:
public string MyProperty
{
get { return (string)GetValue(MyPropertyProperty); }
set
{
SetValue(MyPropertyProperty, value);
}
}
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("MyProperty", typeof(string), typeof(MyUserControl), new PropertyMetadata(null, OnPropertyChanged));
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if ((string)e.NewValue != (string)e.OldValue)
{
Debug.WriteLine(e.NewValue);
}
}
如果你想在你的UserControl
中使用绑定字符串,你可以使用UserControl
的MyProperty
。例如:
在你的 UserControl
:
<UserControl Name="root" ...>
<StackPanel>
<TextBlock Text="{Binding MyProperty, ElementName=root}" />
</StackPanel>
</UserControl>
然后当你使用<local:MyUserControl MyProperty="{Binding myString}"/>
时,你的UserControl
会显示myString
的值。