我正在尝试做一些简单的事情 - 创建一个DependencyProperty然后绑定到它。但是,当我启动应用程序时,getter似乎没有触发。 (我猜这个解决方案会让我咂嘴,然后去“Doh!”,但仍然。:))
有什么想法吗?
代码隐藏代码:
public static readonly DependencyProperty PriorityProperty =
DependencyProperty.Register("Priority",
typeof (Priority), typeof (PriorityControl), null);
public Priority Priority
{
get { return (Priority)GetValue(PriorityProperty); }
set { SetValue(PriorityProperty, value); }
}
控制XAML:
<ListBox Background="Transparent"
BorderThickness="0"
ItemsSource="{Binding Path=Priorities}"
Name="PriorityList"
SelectedItem="{Binding Path=Priority, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="16" Width="16">
<Border BorderBrush="Black"
BorderThickness="2"
CornerRadius="3"
Visibility="{Binding RelativeSource=
{RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected, Converter={StaticResource boolToVisibilityConverter}}" />
<Border CornerRadius="3" Height="12" Width="12">
<Border.Background>
<SolidColorBrush Color="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=Content, Converter={StaticResource priorityToColorConverter}}" />
</Border.Background>
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
绑定声明:
<UI:PriorityControl Grid.Column="8"
Priority="{Binding Path=Priority}"
VerticalAlignment="Center"/>
其他一些说明:
编辑:我已经尝试了两件事。首先,我双向绑定了值,但这没有用。然后,我将一个属性更改回调添加到依赖项属性并使其调用OnPropertyChanged,如下所示:
public static readonly DependencyProperty PriorityProperty =
DependencyProperty.Register("Priority", typeof (Priority), typeof (PriorityControl), new PropertyMetadata(HandleValueChanged));
private static void HandleValueChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var npc = dependencyObject as PriorityControl;
npc.OnPropertyChanged("Priority");
}
这也不起作用。我甚至尝试在控件上覆盖ApplyTemplate以强制执行属性更改通知,但是在初始加载时永远不会设置该值。我可以改变价值观,看到一切都很好,但这是第一次没有任何事情发生。
答案 0 :(得分:1)
除了之外的任何人都不会调用DependencyProperty的getter和setter!
它们只是为了您的利益而生成的帮助程序(为了节省大量的转换和对GetValue / SetValue的调用)。
DP中的所有工作(动画,绑定等)都是通过调用SetValue和GetValue直接发生的。
如果您需要捕获值的更改,请在注册调用中提供更改回调。
注意: 附加属性(即使用RegisterAttached
代替Register
)实际上在解析XAML时确实使用了setter, ,但这是another story,正常的DP不会。
您没有在Register中设置默认值,因此它默认为0(这是您的枚举值“Normal”)。如果将其设置为绑定中的第一个值,则不会更改,因此不会触发。
一个解决方案:添加“无”枚举作为您的前0值,以便“正常”(值1)将导致更改。或者在寄存器中设置一个非“正常”的默认值。
答案 1 :(得分:1)
我注意到,在执行依赖项属性时,如果在属性定义期间已经设置了值,则它将无法正确执行。您已经说过在应用程序中设置值时没有问题,因此我将假设没有管道问题。
考虑以下示例:
<强> XAML 强>
<UI:PriorityControl Priority="{Binding Path=Priority, Mode=TwoWay}"/>
<强>代码强>
public enum Priority
{
Normal,
Low,
High
}
public class PriorityControl : UserControl
{
public static readonly DependencyProperty PriorityProperty =
DependencyProperty.Register("Priority", typeof(Priority), typeof(PriorityControl), new PropertyMetadata(DependencyProperty.UnsetValue, OnPriorityPropertyChanged);
public Priority Priority
{
get { return (Priority)this.GetValue(PriorityProperty); }
set { this.SetValue(PriorityProperty, value); }
}
private static void OnPriorityPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
PriorityControl control = sender as PriorityControl;
if (control != null)
{
// Do what you wanted to here.
}
}
}
如果您正在使用枚举,并且没有指定默认值(在创建时未通过向依赖项属性提供PropertyMetadata对象而出现这种默认值),则默认值将为枚举值的默认值。 ; s默认值。在我上面的例子中,&#34; Normal&#34;。现在,如果您在创建控件时尝试将值设置为Normal,则不会调用回调,因为该值已经等于该值。
为了使其正常工作,您必须像我在定义属性时所做的那样将DependencyProperty.UnsetValue传递给PropertyMetadata对象。这将允许在最初设置值时调用OnPriorityPropertyChanged方法。
希望有助于解决它!
答案 2 :(得分:0)
不是100%肯定,但可能就像将Priority绑定更改为TwoWay一样简单。
<UI:PriorityControl Grid.Column="8"
Priority="{Binding Path=Priority, Mode=TwoWay}"
VerticalAlignment="Center"/>