C# 从DependencyProperty的PropertyChangedCallback中的代码隐藏设置绑定
我试图实现一个C# 从DependencyProperty的PropertyChangedCallback中的代码隐藏设置绑定,c#,wpf,binding,dependency-properties,code-behind,C#,Wpf,Binding,Dependency Properties,Code Behind,我试图实现一个UserControl,它承载绑定到它的某些属性的其他控件。在我的例子中,它将在NumericUpDown旁边显示一个滑块-两个控件都将绑定到UserControl的值属性。我的方法是为每个控件定义一个dependencProperty,因此在使用此控件时,仍然可以通过将新滑块设置为相应属性的值来更改Minimum、TickPlacement等属性: <!-- Displays a slider with default properties next to a text b
UserControl
,它承载绑定到它的某些属性的其他控件。在我的例子中,它将在NumericUpDown
旁边显示一个滑块-两个控件都将绑定到UserControl
的值
属性。我的方法是为每个控件定义一个dependencProperty
,因此在使用此控件时,仍然可以通过将新滑块设置为相应属性的值来更改Minimum
、TickPlacement
等属性:
<!-- Displays a slider with default properties next to a text block-->
<Foo/>
<!-- Displays a sider with custom properties -->
<Foo>
<Foo.Slider>
<Slider Maximum="500" TickPlacement="Both" TickFrequency="20"/>
</Foo.Slider>
</Foo>
XAML代码的相关部分如下所示:
public partial class Foo : UserControl
{
public Foo()
{
InitializeComponent();
Slider = new Slider();
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(nameof(Value), typeof(double), typeof(Foo), new PropertyMetadata(0.0));
public double Value
{
get => (double)GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
public static readonly DependencyProperty SliderProperty = DependencyProperty.Register(nameof(Slider), typeof(Slider), typeof(Foo),
new PropertyMetadata(
new PropertyChangedCallback((obj, e) =>
{
Slider slNew = (Slider)e.NewValue;
if (slNew == null)
obj.SetValue(SliderProperty, new Slider());
else
slNew.SetBinding(ValueProperty,
new Binding("Value")
{
Source = obj,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
Mode = BindingMode.TwoWay
});
})));
public Slider Slider
{
get => (Slider)GetValue(SliderProperty);
set => SetValue(SliderProperty, value ?? new Slider());
}
}
<UserControl x:Name="ctrlBase" [...]>
<Grid [...]>
<Grid.ColumnDefinitions [...]/>
<ContentControl DataContext="{Binding ElementName=ctrlBase}"
Content="{Binding Path=Slider}"/>
<!-- NumericUpDown to be implemented -->
<TextBlock Grid.Column="1"
Text="{Binding ElementName=ctrlBase, Path=Value}/>
</Grid>
</UserControl>
您使用了错误的ValueProperty
。它应该是Slider类中的一个,而不是Foo.ValueProperty
:
slNew.SetBinding(Slider.ValueProperty, new Binding("Value") { ... });
如果您使用的是Slider.ValueProperty.AddOwner
而不是dependencProperty.Register
,那么它就可以工作了
也就是说,更简单的方法可能是在UserControl的XAML中声明一个滑块,并在实例化期间在Foo资源中提供默认滑块样式:
<Foo ...>
<Foo.Resources>
<Style TargetType="Slider">
...
</Style>
</Foo.Resources>
</Foo>
...