我可以在 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;
}
结果是:
如何同时使用添加和过滤功能?
谢谢
从您的解释中我了解到:当视图启动时,
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
};
};
}