【问题标题】:WPF ObservableCollection not updating viewWPF ObservableCollection 不更新视图
【发布时间】:2015-11-22 18:31:06
【问题描述】:

这是 xaml 部分

<ItemsControl x:Name="EventsTop">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Margin="0,1,0,0">
                                <Button Content="{Binding Name}" Template="{DynamicResource ButtonFirst}" Height="50" Margin="15,0,0,0" Padding="10,0,15,0" FontSize="19" FontFamily="/Resources/Fonts/Font Awesome/#FontAwesome" BorderThickness="5,0,0,0" BorderBrush="#8CC152" Background="#2980B9" HorizontalContentAlignment="Left" Foreground="Black" Click="TabOpen" Tag="{Binding Id}"></Button>
                                <StackPanel Background="#2980B9" Margin="15,0,0,5" Visibility="Collapsed" AllowDrop="True" Tag="{Binding Id}" Drop="RowDrop">
                                    <Border BorderThickness="5,0,0,0" BorderBrush="#8CC152">
                                        <StackPanel>
                                            <DockPanel LastChildFill="False">
                                                <Label DockPanel.Dock="Left" Width="140" Content="Date" FontSize="19" BorderThickness="0,0,0,1"   FontFamily="/Resources/Fonts/Open Sans/#Open Sans" BorderBrush="Black" HorizontalContentAlignment="Center"></Label>
                                                <Label DockPanel.Dock="Left" Width="190" Content="Event"  FontSize="19" BorderThickness="0,0,0,1" FontFamily="/Resources/Fonts/Open Sans/#Open Sans" BorderBrush="Black" HorizontalContentAlignment="Center"></Label>
                                                <Label DockPanel.Dock="Left" Width="100" Content="Select" FontSize="19" BorderThickness="0,0,0,1" FontFamily="/Resources/Fonts/Open Sans/#Open Sans" BorderBrush="Black" HorizontalContentAlignment="Center"></Label>
                                            </DockPanel>
                                            <ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="150">
                                                <ItemsControl ItemsSource="{Binding Details}">
                                                    <ItemsControl.ItemTemplate>
                                                        <DataTemplate>
                                                            <DockPanel LastChildFill="False">
                                                                <Label Content="{Binding Date}" DockPanel.Dock="Left" Width="140" FontSize="19" BorderThickness="0" FontFamily="/Resources/Fonts/Open Sans/#Open Sans" BorderBrush="Black" HorizontalContentAlignment="Center"></Label>
                                                                <Label Content="{Binding EventName}" DockPanel.Dock="Left" Width="165" FontSize="19" BorderThickness="0" FontFamily="/Resources/Fonts/Open Sans/#Open Sans" BorderBrush="Black" HorizontalContentAlignment="Center"></Label>
                                                                <Border Width="97">
                                                                    <CheckBox VerticalAlignment="Center" HorizontalAlignment="Center" IsChecked="{Binding Checked}"></CheckBox>
                                                                </Border>
                                                                <Button Width="25" DockPanel.Dock="Left" Content="&#xf08d;" BorderThickness="0" Background="Transparent"  FontFamily="/Resources/Fonts/Font Awesome/#FontAwesome"></Button>
                                                            </DockPanel>
                                                        </DataTemplate>
                                                    </ItemsControl.ItemTemplate>
                                                </ItemsControl>
                                            </ScrollViewer>
                                        </StackPanel>
                                    </Border>
                                </StackPanel>
                            </StackPanel>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>

这是 xaml.cs

 private void WindowLoaded(object sender, RoutedEventArgs e)
    {
        EventHelper eventHelper = new EventHelper();

        TopEvents = eventHelper.GetSports(EventHelper.EventGroup.Top);
        foreach (Sport item in TopEvents)
        {
            item.Name = "\uf196 " + item.Name;
        }
        EventsTop.ItemsSource = TopEvents;

        AllEvents = eventHelper.GetSports(EventHelper.EventGroup.All);
        foreach (Sport item in AllEvents)
        {
            item.Name = "\uf196 " + item.Name;
        }
        EventsAll.ItemsSource = AllEvents;

        Sport.ItemsSource = eventHelper.GetSports(EventHelper.EventGroup.All);
    }

    private void RowMouseDown(object sender, MouseButtonEventArgs e)
    {
        DockPanel currentRow = (DockPanel) sender;
        int rowOffset = Convert.ToInt32(currentRow.Tag);
        DragDrop.DoDragDrop(currentRow,rowOffset,DragDropEffects.Copy);
    }

    private void RowDrop(object sender, DragEventArgs e)
    {
        int rowOffset = (int) e.Data.GetData(typeof (int));
        AllEvents[0].Name = "1";
    }

也是我收藏中的模型

class Sport : INotifyPropertyChanged
{
    private int _id;
    private string _name = string.Empty;
    private ObservableCollection<Details> _details = new ObservableCollection<Details>();

    public int Id
    {
        get { return _id; }
        set { _id = value; }
    }

    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            NotifyPropertyChanged("Content");
        }
    }

    public ObservableCollection<Details> Details
    {
        get { return _details; }
        set { _details = value; }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
            MessageBox.Show(info);
        }
    }
}

所以当我更改属性时,它会抛出 MessageBox 但不更新 GUI。

我在 xaml.cs 我正在调用方法 GetEvents 那就是 返回 ObservableCollection

我想将Name 更改为Sport 中的ObservableCollaction&lt;Sport&gt; AllEvents

您可以在 xaml.cs 中的 RowDrop 方法中看到它 在调试中,我注意到 AllEvents[0].Name 已更改但视图未更新

更新

ObservabelCollection 声明的一部分

public MainPage()
    {
        InitializeComponent();
        AllEvents = new ObservableCollection<Sport>();
        TopEvents = new ObservableCollection<Sport>();
        EventsTop.ItemsSource = TopEvents;
        EventsAll.ItemsSource = AllEvents;
    }

    private ObservableCollection<Sport> AllEvents;
    private ObservableCollection<Sport> TopEvents;

第二次更新 我发现当我使用窗口激活事件时它正在工作

【问题讨论】:

  • NotifyPropertyChanged("Content"); 替换为NotifyPropertyChanged("Name");
  • 你好,我改了,但是还不行
  • 显示更改值的代码。是这一行吗:AllEvents[0].Name = "1";
  • 请显示所有事件的声明
  • 嗨,我添加了部分声明,

标签: c# wpf observablecollection


【解决方案1】:

我找到了解决办法。

所以,ObservableCollection 工作得很好但是,它需要刷新 为了出现在视图中,我们需要使用

CollectionViewSource.GetDefaultView(ObservableCollection).Refresh() 方法

我认为它会帮助某人

【讨论】:

  • 这是为我做的。非常感谢您的分享!过去两天我一直在试图弄清楚为什么我的视图没有更新
【解决方案2】:

传递给NotifyPropertyChanged 方法的属性的问题。参数名称应为属性名称。请将 Name 属性更改为

public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            NotifyPropertyChanged("Name");
        }
    }

【讨论】:

  • 什么Template="{DynamicResource ButtonFirst}" 覆盖了按钮的内容dp?
  • 它只是按钮的模板
  • 当我将项目添加到 AllEvents 时,它会更新 GUI
  • 你是在更新绑定集合的同一个实例
【解决方案3】:

使用CallerMemberNameAttribute 避免必须正确命名并允许重构:

private void NotifyPropertyChanged([CallerMemberName] string info = null)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(info));
        MessageBox.Show(info);
    }
}

public string Name
{
    get { return _name; }
    set
    {
        _name = value;
        NotifyPropertyChanged(); //now no need to specify
    }
}

每个属性设置器都应该通知属性更改,所以:

public IEnumerable<Details> Details //note IEnumerable, no calling code needs to know its concrete type
{
    get { return _details; }
    set
    {
        _details = value;
        NotifyPropertyChanged();
    }
}

使用observable range collection,您可以这样做:

private readonly ObservableRangeCollection<Details> _details = new ObservableRangeCollection<Details>();

public IEnumerable<Details> Details
{
    get { return _details; }
    set { _details.Replace(value); }
}

【讨论】:

  • 实现 INotifyPropertyChanged 的​​好方法,它们应该对 OP 有帮助,但在这种情况下需要刷新的集合是 AllEvents,它似乎是实际视图的一部分,而不是视图模型。在这种情况下,集合永远不会“重新设置”。
【解决方案4】:

来自MSDN

在添加、删除、更改、移动或整个项目时发生 列表已刷新。

changed 并不是指子属性何时发生变化,而是指你在任何索引处更改项时。

因此,当您修改集合项时,您需要通知绑定属性已更改。修改集合中的项目后,从窗口的视图模型中,您会通知集合已更改。

NotifyPropertyChanged("AllEvents"); 

【讨论】:

    猜你喜欢
    • 2011-08-25
    • 2011-10-28
    • 2014-04-06
    • 2017-08-31
    • 2021-04-19
    • 2021-11-15
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多