WPF:UserControl DataBinding PropertyChanged不起作用

时间:2017-08-23 19:30:23

标签: c# wpf xaml user-controls

我有一个使用UserControl的Window(以编程方式定义)。我的窗口使用Object WindowDatas作为DataContext。该对象包含一个对象PJDataContext,它定义了UserControl的数据(代码模块性)。

问题是我无法使用PropertyChanged事件更新UserControl的ListView。但是,我知道绑定在初始化时是正确的,因为如果我的列表不为空,我在屏幕上有一些东西。

这是代码: UserControl XAML(简化,不考虑Grid.Row属性)

<UserControl x:Class="DandDAdventures.XAML.Controls.PJView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:DandDAdventures.XAML.Controls"
             xmlns:db="clr-namespace:DandDAdventures"
             xmlns:sys="clr-namespace:System;assembly=mscorlib"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" DataContext="{Binding PJDatas}">
    <Grid>

        <Grid.RowDefinitions>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>

        <Grid Grid.Row="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1"/>
                <ColumnDefinition Width="2*"/>
            </Grid.ColumnDefinitions>
            <ListView Grid.Column="0" ItemsSource="{Binding Path=EventList, UpdateSourceTrigger=PropertyChanged}">
                <ListView.Resources>
                    <DataTemplate DataType="{x:Type db:GroupEvent}">
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="["/>
                            <TextBlock Text="{Binding ID}"/>
                            <TextBlock Text="]"/>
                        </StackPanel>
                    </DataTemplate>
                </ListView.Resources>
            </ListView>
            <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" ></GridSplitter>
            <TextBlock Grid.Column="2"></TextBlock>
        </Grid>
    </Grid>
</UserControl>

UserControl DataContext:

public class PJDataContext : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public List<GroupEvent> m_groupEvent; //The List

    public PJDataContext()
    {
        m_groupEvent = new List<GroupEvent>();
    }

    public void AddGroupEvent(GroupEvent ge)
    {
        m_groupEvent.Add(new GroupEvent { ID = 25 });
        m_groupEvent.Add(ge);
        this.EventList = m_groupEvent; //Using PropertyChanged
    }

    public void OnPropertyChanged(string name)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }

    public List<GroupEvent> EventList { get => m_groupEvent; set { m_groupEvent = value; OnPropertyChanged("EventList"); } }
}

Window DataContext:

public class WindowData : INotifyPropertyChanged
{
    protected PJDataContext m_pjDatas;

    public event PropertyChangedEventHandler PropertyChanged;

    public WindowData()
    {
        m_pjDatas = new PJDataContext();
    }

    public void OnPropertyChanged(string name)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }

    public String CurrentPJ
    {
        get => m_currentPJ;
        set
        {
           m_currentPJ = value;
        }
     }            
     public PJDataContext PJDatas { get => m_pjDatas; }
}

谢谢!

1 个答案:

答案 0 :(得分:1)

虽然行

this.EventList = m_groupEvent;
在AddGroupEvent方法中

触发PropertyChanged事件,EventList绑定将忽略该事件,因为底层集合实例未更改。

您应该使用ObservableCollection作为EventList属性,这也将大大简化您的视图模型类:

public class PJDataContext
{
    public ObservableCollection<GroupEvent> EventList { get; }
        = new ObservableCollection<GroupEvent>();

    public void AddGroupEvent(GroupEvent ge)
    {
        EventList.Add(ge);
    }
}

现在,即使AddGroupEvent方法似乎也是多余的。