WPF TargetUpdated事件未在ContentControl上触发

时间:2014-05-02 12:14:52

标签: wpf datatemplate contentcontrol

我使用附加属性从TextBlock订阅TargetUpdated事件,因此每次文本更改时都会通知我。

使用以下XAML:

                                                                                                                                                

    <DataTemplate DataType="{x:Type targetUpdatedApp:Item}">
        <targetUpdatedApp:LabelControl Text="{Binding Text, NotifyOnTargetUpdated=True}" Style="{StaticResource LabelTemplateStyle}"/>
    </DataTemplate>
</Window.Resources>

<StackPanel>
    <ListBox ItemsSource="{Binding Items}">
        <!--<ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Text, NotifyOnTargetUpdated=True}" targetUpdatedApp:DesiredWidth.DesiredMinWidth="120"/>
            </DataTemplate>
        </ListBox.ItemTemplate>-->
    </ListBox>

    <Button Click="ButtonBase_OnClick">Button</Button>
</StackPanel>

这是我的AttachedProperty代码:

public class DesiredWidth
{
    public static readonly DependencyProperty DesiredMinWidthProperty =
        DependencyProperty.RegisterAttached(
            "DesiredMinWidth", typeof (double),
            typeof (TextBlock), new PropertyMetadata(OnDesiredMinWidthChanged));

    public static double GetDesiredMinWidth(DependencyObject obj)
    {
        return (double) obj.GetValue(DesiredMinWidthProperty);
    }

    public static void SetDesiredMinWidth(DependencyObject obj, double value)
    {
        obj.SetValue(DesiredMinWidthProperty, value);
    }

    static void OnDesiredMinWidthChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        var textBlock = obj as TextBlock;
        if (textBlock == null)
        {
            return;
        }

        if (args.NewValue != null)
        {
            textBlock.TargetUpdated += OnTextBoxTargetUpdated;     
        }
    }

    static void OnTextBoxTargetUpdated(object sender, System.Windows.Data.DataTransferEventArgs e)
    {
        if (e.Property == TextBlock.TextProperty)
        {

        }
    }
}

绑定到ListBox的Items集合是ObservableCollection,其上的项目实现INotifyPropertyChanged。 如果我取消注释ListBox.ItemTemplate的代码并使用它代替它可以正常工作的样式,但是我使用了DependencyProperty事件样式上描述的LabelControl(基本上有一个Text TargetUpdated)订阅AttachedProperty永远不会被解雇。

有人可以就这个问题给我一些帮助吗? 提前谢谢。

PS:从评论中添加:

<Style x:Key="LabelTemplateStyle" TargetType="{x:Type argetUpdatedApp:LabelControl}">      
     <Setter Property="Template"> 
         <Setter.Value> 
             <ControlTemplate TargetType="{x:Type targetUpdatedApp:LabelControl}"> 
                 <TextBlock Text="{TemplateBinding Text}" TargetUpdatedApp:DesiredWidth.DesiredMinWidth="120"/> 
             </ControlTemplate> 
         </Setter.Value> 
     </Setter> 
</Style>

1 个答案:

答案 0 :(得分:0)

NotifyOnTargetUpdated仅适用于它所设置的绑定,而不适用于其中包含的元素的绑定。您在LabelControl上设置了此设置,但事件处理程序已附加到其ControlTemplate内的TextBlock,它不会通知。使用:

<ControlTemplate TargetType="{x:Type targetUpdatedApp:LabelControl}">
    <TextBlock Text="{TemplateBinding Text, NotifyOnTargetUpdated=True}" targetUpdatedApp:DesiredWidth.DesiredMinWidth="120"/>
</ControlTemplate>

另一种不需要编辑绑定的方法是使用另一个附加属性而不是元素自己的Text属性:

<TextBlock DesiredWidth.Text="{Binding Text}" DesiredWidth.MinWidth="120" />

然后在DesiredWidth中,您可以添加一个OnTextChanged回调函数,将值传递给TextBlock的Text并进行其他任何处理。