wpf 如何简单地通过项目属性过滤一个组合框中的集合(视图)(数据网格)?

pkmbmrz7  于 2023-01-18  发布在  其他
关注(0)|答案(1)|浏览(171)

经过几个星期几个小时的搜索(在SO和Google,我甚至问了ChatGPT),我还是没能找到我的(简单?)问题的解决方案,尽管我已经接近我想要的结果。

    • 我有什么:**我有一个c#wpf xaml应用程序,在那里我显示一些datagrid(作为CollectionViewSource),其中任何一个都由List<MyModel>填充,其中每个模型包含不同的字符串作为属性。我已经在XAML中使用它们作为CollectionView,在代码后面有一个过滤器,并可以显示列表。
    • XAML格式:**
<Page.Resources>
     <CollectionViewSource Filter="MyFilter" Source="{Binding Aktie.AktieBuchwerte}" x:Key="AktieBuchwerte" CollectionViewType="ListCollectionView">
         <CollectionViewSource.SortDescriptions>
             <scm:SortDescription PropertyName="Datum" Direction="Descending"/>
     </CollectionViewSource.SortDescriptions>
</Page.Resources>

<ComboBox ItemsSource="{Binding Aktie.AktieBuchwerte}"
          Margin="{StaticResource SmallLeftMargin}"
          DisplayMemberPath="Quelle"
          SelectedValuePath="Quelle"
          x:Name="BuchWertComboBox"
          SelectedValue="Marketscreener"/>

<DataGrid
          AutoGenerateColumns="False"
          GridLinesVisibility="All"
          IsReadOnly="True"
          CanUserAddRows="False"
          ItemsSource="{Binding Source={StaticResource AktieBuchwerte}}"
          KeyboardNavigation.TabNavigation="Once">
          <DataGrid.Resources>
              <Style BasedOn="{StaticResource {x:Type DataGridColumnHeader}}" TargetType="{x:Type DataGridColumnHeader}">
                    <Setter Property="Background" Value="DimGray" />
              </Style>
          </DataGrid.Resources>
          <DataGrid.Columns>
              <DataGridTextColumn Binding="{Binding Datum, StringFormat=yyyy}" Header="Jahr" />
              <DataGridTextColumn Binding="{Binding Value, ConverterCulture=de-de}" Header="Buchwert" />
              <DataGridTextColumn Binding="{Binding Schätzung, ConverterCulture=de-de}" Header="Schätzung" />
              <DataGridTextColumn Binding="{Binding Quelle, ConverterCulture=de-de}" Header="Quelle" />
          </DataGrid.Columns>
</DataGrid>
    • 隐藏代码:**

一个一个一个一个一个x一个一个二个一个x一个一个三个一个x一个一个x一个四个一个
Actual result ComboBox & ListActual result ComboBox dropdown & List

    • 我自己做了无休止的研究后,我不能/在哪里我需要一些帮助:**我不能:
    • A:**去掉下拉框中显示的多行。在这种情况下基本上有两个值:字符串值A(Boerse.de)或字符串值B(Marketscreener),我希望ComboBox只显示底层列表中PropertyField "Quelle"中可用的单个值,而不显示每个对象的每个属性值(正常的过滤器行为,我会这样做吗?)
    • B:**动态过滤列表。如果我将"Marketscreener"或"www.example.com"硬编码到组合框的"SelectedValue"中,我只能看到列表中的项目。好的方面是,我可以看到相应的正确项目(例如,如果选择Marketscreener,则只能看到),但只要我尝试将绑定附加到选定值字段,我的列表就为空,例如:Boerse.deDynamic selected value:SelectedValue="{Binding Source={StaticResource AktieBuchwerte}, Path=Quelle}" is giving me following result: Dynamic selected value:

我试过许多不同的组合,甚至我现在有一个过滤器是小时和小时的研究。我不敢相信,像过滤列表这样微不足道的事情是不可能在一些少量的代码行?
如果有人能给出正确的答案,我会很高兴的...最好的问候pidoss.:对于那些对ChatGPT的答案感到好奇的人,这里有:ChatGPTs answer on my Question

yqlxgs2m

yqlxgs2m1#

我通常使用一个额外的列表属性来做这样的事情。这个解决方案并不完美,但简单有效。
它还允许您添加更多的过滤器逻辑,如果需要的话。

视图模型(数据网格详细信息视图模型):

public async void OnNavigatedTo(object parameter)
{
    if (parameter is int id)
        await Initialize(id);
}

private async Task Initialize(int id)
{
    Aktie = await _SQLiteDataService.GetGridDetailDataAsync(id);
    var quellen = Aktie.AktieBuchwerte.GroupBy(buchwert => buchwert.Quelle).Select(group => group.Key).ToList();
    quellen.ForEach(quelle => Quellen.Add(quelle));
    SelectedQuelle = quellen.FirstOrDefault();
}

public ObservableCollection<string> Quellen { get; set; } = new ObservableCollection<string>();

public List<Buchwert> FilteredBuchwerte => GetFilteredBuchwerte();

public string SelectedQuelle
{
    get => _selectedQuelle;
    set
    {
        if (Equals(value, _selectedQuelle))
            return;
        _selectedQuelle = value;
        OnPropertyChanged(nameof(SelectedQuelle));
        // make the UI fetch the filtered list again
        OnPropertyChanged(nameof(FilteredBuchwerte));
    }
}

public Aktie Aktie
{
    get => _aktie;
    set
    {
        if (Equals(value, _aktie))
            return;
        _aktie = value;
        OnPropertyChanged(nameof(Aktie));
        // make the UI fetch the filtered list again
        OnPropertyChanged(nameof(FilteredBuchwerte));
    }
}

private List<Buchwert> GetFilteredBuchwerte()
{
    if (Aktie?.AktieBuchwerte == null)
        return new List<Buchwert>();
    IEnumerable<Buchwert> buchwerte = Aktie.AktieBuchwerte.ToList();
    buchwerte = buchwerte.Where(buchwert => buchwert.Quelle == SelectedQuelle);
    buchwerte = buchwerte.OrderByDescending(buchwert => buchwert.Datum);
    return buchwerte.ToList();
}

setter也可以类似于:

set
{
    SetProperty(ref _selectedQuelle , value);
    // make the UI fetch the filtered list again
    OnPropertyChanged(nameof(FilteredBuchwerte));
}

只要确保UI也被通知过滤列表已更改即可。

查看:

那么,您将不再需要<Page.Resources>块,代码中的MyFilter()也将不再需要。

<ComboBox ItemsSource="{Binding Quellen}"
          Margin="{StaticResource SmallLeftMargin}"
          SelectedValue="{Binding SelectedQuelle, UpdateSourceTrigger=PropertyChanged}" />

<DataGrid AutoGenerateColumns="False"
          GridLinesVisibility="All"
          IsReadOnly="True"
          CanUserAddRows="False"
          KeyboardNavigation.TabNavigation="Once"
          ItemsSource="{Binding FilteredBuchwerte}">
[...]
</DataGrid>

**编辑:**为GetFilteredBuchwerte()添加了空检查。

相关问题