XAML: свойство объекта DependencecyObject не обновляется, если оно является элементом присоединенной коллекции

У меня есть DependencyObject внутри присоединенного свойства зависимости (это коллекция). Привязка к этому объекту по какой-то причине не работает.

В моем примере я привязываю две вещи: базовое присоединенное свойство (local:CollHolder.BasicProperty) и обычное зависимое свойство (local:MyItem.MyData) - оба связаны с Text элемента управления TextBox. XAML выглядит так:

<ListView ItemsSource="{x:Bind Items}">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="x:String">
            <StackPanel x:Name="stack" local:CollHolder.BasicProperty="{Binding ElementName=text, Path=Text}" VerticalAlignment="Center" HorizontalAlignment="Center" >
                <TextBox Text="" x:Name="text"/>
                <local:CollHolder.Coll>
                    <local:MyItem MyData="{Binding ElementName=text, Path=Text}"/>
                </local:CollHolder.Coll>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Когда происходят изменения в свойстве Text, они распространяются на присоединенное свойство, но не на свойство зависимости.

CollHolder:

public class CollHolder : DependencyObject
{
    public static readonly DependencyProperty BasicPropertyProperty =
        DependencyProperty.RegisterAttached("BasicProperty", typeof(string), typeof(CollHolder), new PropertyMetadata("", DPC));
    public static readonly DependencyProperty CollProperty =
        DependencyProperty.RegisterAttached("Coll", typeof(Coll), typeof(CollHolder), new PropertyMetadata(null));
    public static Coll GetColl(DependencyObject obj)
    {
        var coll = (Coll)obj.GetValue(CollProperty);
        if (coll == null)
        {
            obj.SetValue(CollProperty, coll = new Coll());
        }

        return coll;
    }

    public static void SetColl(DependencyObject obj, Coll value)
    {
        obj.SetValue(CollProperty, value);
    }


    public static string GetBasicProperty(DependencyObject obj)
    {
        return (string)obj.GetValue(BasicPropertyProperty);
    }

    public static void SetBasicProperty(DependencyObject obj, string value)
    {
        obj.SetValue(BasicPropertyProperty, value);
    }


    private static void DPC(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Debug.WriteLine("Basic Property changed");
    }
}

MyItem:

public class MyItem : DependencyObject
{
    public string MyData
    {
        get { return (string)GetValue(MyDataProperty); }
        set { SetValue(MyDataProperty, value); }
    }

    // Using a DependencyProperty as the backing store for MyData.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MyDataProperty =
        DependencyProperty.Register("MyData", typeof(string), typeof(MyItem), new PropertyMetadata("", DPC));



    private static void DPC(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Debug.WriteLine("CHANGED!!");
    }
}

А сборник довольно простой:

public class Coll : List<MyItem>
{
}

person Shahar Prish    schedule 27.02.2018    source источник


Ответы (1)


Когда происходят изменения в свойстве Text, они распространяются на присоединенное свойство, но не на свойство зависимостей.

<TextBox Text="" x:Name="text"/>
<local:CollHolder.Coll>
  <local:MyItem MyData="{Binding ElementName=text, Path=Text}"/>
</local:CollHolder.Coll>

TextBox и local:MyItem в том же DataContext, вы можете использовать {x:Bind } для непосредственного получения текстового значения.

<TextBox Text="{x:Bind }" x:Name="text" />
<local:CollHolder.Coll>
    <local:MyItem  MyData="{x:Bind }" />
</local:CollHolder.Coll>

Обновить

Я попытался заменить MyItem на Control, чтобы проверить, работает ли DependencyProperty в режиме Binding. Работает как положено. Итак, вы можете использовать Control в качестве базового класса MyItem.

public class MyItem : Control
 {
     public string MyData
     {
         get { return (string)GetValue(MyDataProperty); }
         set { SetValue(MyDataProperty, value); }
     }

     // Using a DependencyProperty as the backing store for MyData.  This enables animation, styling, binding, etc...
     public static readonly DependencyProperty MyDataProperty =
         DependencyProperty.Register("MyData", typeof(string), typeof(MyItem), new PropertyMetadata("", DPC));

     private static void DPC(DependencyObject d, DependencyPropertyChangedEventArgs e)
     {
         Debug.WriteLine("CHANGED!!");
     }
 }
person Nico Zhu - MSFT    schedule 28.02.2018
comment
Не могу использовать x: Bind - моя реальная ситуация на самом деле заключается в том, что привязка должна происходить в DataTemplate. Я не могу использовать x: Bind для прикрепленного свойства, потому что мне нужно, чтобы оно было в элементе. - person Shahar Prish; 28.02.2018
comment
Пометка как ответ, хотя наследование от Control кажется очень тяжелым с точки зрения памяти ... - person Shahar Prish; 01.03.2018