添加更多代码行后,与 Datagid 的绑定并不总是有效

问题描述 投票:0回答:1

我可以在 WPF 中将可观察列表绑定到数据网格,但在向数据网格添加自定义过滤功能时我失去了绑定

我在WPF中创建了一个包含DataGrid的用户控件,DataGrid绑定到变量“FilteredCollection”

        public ObservableCollection<cs_Log> FilteredCollection
        {
            get { return _filteredcollection; }
            set { _filteredcollection = value; OnPropertyChanged("FilteredCollection"); dgLogger.ItemsSource = _filteredcollection; }
        }

当我调用以下函数时,数据将被复制并且数据网格正确显示新添加的行

        void ApplyFilter()
        {
            FilteredCollection = csGlobal.LogList;
        }

后来我添加了一个用于过滤的复选框,并将其绑定到变量“InfoInclude”,我还修改了函数

        public bool InfoInclude
        {
            get { return _infoinclude; }
            set { _infoinclude = value; OnPropertyChanged("InfoInclude"); ApplyFilter(); }
        }

        void ApplyFilter()
        {
            ObservableCollection<cs_Log> TempCollection = new ObservableCollection<cs_Log>();
            foreach (cs_Log item in csGlobal.LogList)
                if (((item.sType == "Information") && InfoInclude) || ((item.sType == "Warning") && WarnInclude) || ((item.sType == "Error") && ErrInclude))
                    TempCollection.Add(item);
            FilteredCollection = TempCollection;
            //FilteredCollection = csGlobal.LogList;
        }

结果是:

  1. 添加新行时,“FilteredCollection”变量已更新,但数据网格未显示新添加的行
  2. 当选中/取消选中复选框时,数据网格会在数据网格上显示过滤后的数据

如何同时使用添加和过滤功能?

谢谢

c# wpf binding
1个回答
0
投票

从您的解释中我了解到:当视图启动时,

FilteredCollection
集合会加载完整的行集合;创建 InfoInclude、WarnInclude、ErrInclude 属性只是为了管理过滤。如果这是正确的,那么在我看来,更优化的过滤实现将是在视图级别。

看这个例子(你没有显示的代码,我根据我的猜测重新创建它):

    public class LogViewModel
    {
        private GlobalModel csGlobal = new()!;

        public LogViewModel()
        {
            FilteredCollection = new(csGlobal.LogList);
        }

        public ObservableCollection<cs_Log> FilteredCollection { get; }

    }

窗口 XAML:

    <Window.DataContext>
        <local:LogViewModel/>
    </Window.DataContext>
    <UniformGrid Columns="2">
        <DataGrid x:Name="dgLog" Margin="10" ItemsSource="{Binding FilteredCollection}"/>
        <UniformGrid Columns="1">
            <CheckBox x:Name="InfoInclude"
                      Content="{Binding Name, RelativeSource={RelativeSource Self}}"
                      Click="OnRefreshFilter"
                      VerticalAlignment="Center" HorizontalAlignment="Center"/>
            <CheckBox x:Name="WarnInclude"
                      Content="{Binding Name, RelativeSource={RelativeSource Self}}"
                      Click="OnRefreshFilter"
                      VerticalAlignment="Center" HorizontalAlignment="Center"/>
            <CheckBox x:Name="ErrInclude"
                      Content="{Binding Name, RelativeSource={RelativeSource Self}}"
                      Click="OnRefreshFilter"
                      VerticalAlignment="Center" HorizontalAlignment="Center"/>
        </UniformGrid>
    </UniformGrid>
</Window>

窗口代码背后:

        private void OnRefreshFilter(object sender, RoutedEventArgs e)
        {
            bool infoinclude = InfoInclude.IsChecked == true;
            bool warnInclude = WarnInclude.IsChecked == true;
            bool errInclude = ErrInclude.IsChecked == true;

            dgLog.Items.Filter = item =>
            {
                cs_Log log = (cs_Log)item;

                return log.sType switch
                {
                    "Information" => infoinclude,
                    "Warning" => warnInclude,
                    "Error" => errInclude,
                    _ => false
                };
            };
        }
© www.soinside.com 2019 - 2024. All rights reserved.