![](/img/trans.png)
[英]WinUI DataGrid (from CommunityToolkit): How to get the currently selected cell?
[英]DataGrid from CommunityToolkit.WinUI.Controls.DataGrid not updating when bound ObservableCollection changes
我有一個包含三個過濾器選項的下拉列表:全部、活動和非活動。 更改所選值會引發一個事件,該事件會調整 ViewModel 中的可觀察集合屬性ProjectDbUsers
,顯示應用程序用戶的 Datagrid 綁定到該屬性。 當我調試時,代碼成功更改了ProjectDbUsers
屬性,但 Datagrid 未刷新/更新以匹配更改后的 object 集合。
注意:我在主 UI 項目中使用CommunityToolkit.WinUI.Controls.DataGrid
package,在包含 ViewModel 的業務層項目中使用CommunityToolkit.Mvvm
package。
代碼:
在Manage Users頁面XAML,顯示Combobox和Datagrid:
<ComboBox x:Name="BasicUserFilter" Grid.Row="0" Grid.Column="1"
Height="30" Width="Auto" Margin="20,10,10,10"
ItemsSource="{x:Bind ViewModel.Filters, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.SelectedFilter, Mode=TwoWay}"
SelectionChanged="BasicUserFilter_SelectionChanged"/>
<controls:DataGrid x:Name="dataGrid1" Grid.Row="2"
Height="600" Margin="12"
AutoGenerateColumns="False"
ItemsSource="{x:Bind ViewModel.ProjectDbUsers, Mode=OneWay}">
<controls:DataGrid.Columns>
<controls:DataGridTextColumn
Header="Name"
Width="250"
Binding="{Binding UserAddisplayName}"
FontSize="14" />
...
</controls:DataGrid.Columns>
</controls:DataGrid>
更改過濾器 Combobox 值時觸發BasicUserFilter_SelectionChanged
事件的隱藏代碼。
private void BasicUserFilter_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ViewModel.UpdateGridBasedOnFilter();
}
ViewModel class 的摘錄,顯示了綁定的屬性定義和過濾器下拉選擇發生變化時調用的方法:
[ObservableProperty]
private string _selectedFilter;
public ObservableCollection<string> Filters { get; } = new ObservableCollection<string>(new List<string>() { "All", "Active", "Inactive" });
public ObservableCollection<UserAd> ProjectDbUsers { get; private set; }
public void UpdateGridBasedOnFilter()
{
using (UnitOfWorkDbGlobal unitOfWorkDbGlobal = new(new MyDBContext()))
{
List<UserAd> users = new();
switch (SelectedFilter)
{
case "All":
users = unitOfWorkDbGlobal.UserAds.GetAllUsers().ToList();
break;
case "Active":
users = unitOfWorkDbGlobal.UserAds.GetAllActiveUsers().ToList();
break;
case "Inactive":
users = unitOfWorkDbGlobal.UserAds.GetAllInactiveUsers().ToList();
break;
}
ProjectDbUsers = new ObservableCollection<UserAd>(users);
}
}
為了在ProjectDbUsers
更改時允許 Datagrid 更新,可能缺少什么?
由於您要重新實例化 projectDbUsers 屬性本身,因此需要將其設為 ObservableProperty。
與您的問題沒有直接關系,但您可以使用CommunityToolkit.Mvvm生成的partial
方法,而不是在代碼隱藏中調用BasicUserFilter_SelectionChanged()
。
請參閱此示例代碼。
using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace DataGridTest;
public enum Filters
{
All,
Active,
Inactive,
}
public class UserAd
{
public string Name { get; set; } = string.Empty;
}
public partial class MainPageViewModel : ObservableObject
{
private List<UserAd> userAdSource = new()
{
new UserAd() { Name = "User A - Active" },
new UserAd() { Name = "User B - Inactive" },
new UserAd() { Name = "User C - Active" },
new UserAd() { Name = "User D - Inactive" },
new UserAd() { Name = "User E - Active" },
};
// The CommunityToolkit.Mvvm auto-generates
// partial void OnSelectedFilterChanged(Filters value).
[ObservableProperty]
private Filters selectedFilter = Filters.All;
// ObservableCollections notifies the UI when you add/remove elements.
// Since you are reinstantiating the projectDbUsers property itself,
// you need to make it ObservableProperty.
//public ObservableCollection<UserAd> ProjectDbUsers { get; set; }
[ObservableProperty]
private ObservableCollection<UserAd>? projectDbUsers;
public MainPageViewModel()
{
IEnumerable<UserAd> filteredUserAds = GetFilteredUserAds(SelectedFilter);
ProjectDbUsers = new ObservableCollection<UserAd>(filteredUserAds);
}
public List<Filters> FilterList { get; } = new(Enum.GetValues<Filters>());
// This "partial method" is auto-generated by the CommunityTookit.Mvvm.
async partial void OnSelectedFilterChanged(Filters value)
{
IEnumerable<UserAd> filteredUserAds = await GetFilteredUserAds(value);
ProjectDbUsers = new ObservableCollection<UserAd>(filteredUserAds);
}
private Task<IEnumerable<UserAd>> GetFilteredUserAds(Filters filter)
{
return await Task.Run(() =>
{
return filter is Filters.All
? this.userAdSource
: this.userAdSource.Where(x => x.Name.Contains(filter.ToString()));
});
}
}
主頁.xaml
<Page
x:Class="DataGridTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:DataGridTest"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ComboBox
Grid.Row="0"
ItemsSource="{x:Bind ViewModel.FilterList}"
SelectedItem="{x:Bind ViewModel.SelectedFilter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<controls:DataGrid
Grid.Row="1"
AutoGenerateColumns="False"
ItemsSource="{x:Bind ViewModel.ProjectDbUsers, Mode=OneWay}">
<controls:DataGrid.Columns>
<controls:DataGridTextColumn
Width="250"
Binding="{Binding Name}"
FontSize="14"
Header="Name" />
</controls:DataGrid.Columns>
</controls:DataGrid>
</Grid>
</Page>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.