2

我有以下xaml;

    <DataTemplate DataType="{x:Type NameSpace:Node}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Item.Value}"/>
            <ContentControl Content="{Binding Item}"/>
        </StackPanel>
    </DataTemplate>

    <DataTemplate DataType="{x:Type NameSpace:Item}">
        <TextBlock Text="{Binding Value}" />
    </DataTemplate>

当我使用 Node 模板显示 Node 对象时,我得到两个 TextBlock,它们都显示相同的值。到现在为止还挺好。项目更改时会出现问题。当 Node 类触发 INotifyPropertyChanged 事件时,Node DataTemplate 中的 TextBlock 会按预期更新,但 Item DataTemplate 中的 TextBlock 不会更新。

当 Node 类触发 IPropertyChanged 事件时,如何让 Item DataTemplate 更新其绑定?

更新 事实证明,上述方法适用于以下简单场景;

Xaml

        <DataTemplate DataType="{x:Type DataTemplateExample:Node}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Item.Value}"/>
                <ContentControl Content="{Binding Item}"/>
            </StackPanel>
        </DataTemplate>

        <DataTemplate DataType="{x:Type DataTemplateExample:Item}">
            <TextBlock Text="{Binding Value}" />
        </DataTemplate>
    </Window.Resources>

    <Grid>
        <StackPanel Orientation="Vertical">
            <ContentControl Content="{Binding MyNode}"/>
            <Button Command="{Binding ChangeMyNodeItem}">Change Item</Button>
        </StackPanel>
    </Grid>
</Window>

C#

public class MainViewModel
{
    private readonly Node myNode;
    private readonly DelegateCommand changeMyNodeItemCmd;

    public MainViewModel()
    {
        myNode = new Node {Item = new Item("a")};
        changeMyNodeItemCmd = new DelegateCommand(()=>
            myNode.Item = new Item("b"));
    }

    public Node MyNode { get { return myNode; } }

    public ICommand ChangeMyNodeItem
    {
        get { return changeMyNodeItemCmd; }
    }
}

public class Node : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private Item item;
    public Item Item
    {
        set
        {
            item = value;
            if (PropertyChanged != null)
                PropertyChanged(this,new PropertyChangedEventArgs("Item"));
        }
        get { return item; }
    }
}

public class Item
{
    private readonly string value;

    public Item(string value)
    {
        this.value = value;
    }

    public string Value
    {
        get { return value; }
    }
}

在我的真实场景中,我使用了代理,我认为这就是让 WPF 感到困惑的原因。项目实际上并没有改变 - 它正在重新映射。

最终,我使用类似于 ShadeOfGray 提出的解决方案解决了这个问题。但我应该指出,除非您使用代理,否则这不是必需的。

4

1 回答 1

3

从您发布的内容来看,我认为您在错误的类中触发了 NotifyPropertyChanged。类似的东西应该在您的场景中正常工作。

根据评论更新:

public class Node : INotifyPropertyChanged
{
    private Item item;

    public event PropertyChangedEventHandler PropertyChanged;

    public Item Item
    {
        get
        {
            return item;
        }

        set
        {
            item = value;

            this.NotifyPropertyChanged("Item");

            if (item != null)
            {
                item.ForcePropertyChanged("Value");
            }
        }
    }

    protected void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

public class Item : INotifyPropertyChanged
{
    private string itemValue;

    public Item()
    {
        this.Value = string.Empty;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public string Value
    {
        get
        {
            return itemValue;
        }

        set
        {
            itemValue = value;

            NotifyPropertyChanged("Value");
        }
    }

    public void ForcePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    protected void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
于 2012-12-05T08:42:10.117 回答