WPF ObservableCollection未更新视图

本文关键字:新视图 更新 ObservableCollection WPF | 更新日期: 2023-09-27 18:23:48

这是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我正在调用方法GetEventsreturn ObservableCollection

我想在ObservableCollaction<Sport> AllEvents 中的Sport中更改Name

您可以在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;

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

WPF ObservableCollection未更新视图

我找到了解决方案。

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

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

我认为它会帮助

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

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

使用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();
    }
}

有了可观测范围集合,你就可以做到这一点:

private readonly ObservableRangeCollection<Details> _details = new ObservableRangeCollection<Details>();
public IEnumerable<Details> Details
{
    get { return _details; }
    set { _details.Replace(value); }
}

来自MSDN。

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

更改并不意味着何时更改子属性,而是指何时更改任何索引处的项。

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

NotifyPropertyChanged("AllEvents");