![](/img/trans.png)
[英]Call method when ObservableProperty changes using CommunityToolkit.Mvvm
[英]How to call events using CommunityToolkit.Mvvm
我正在“嘗試”在 WPF 應用程序中使用 C# 學習 MvvM 架構。 我很快意識到我正在編寫大量的重復樣板,因此我決定安裝 NuGet CoummunityToolkit.Mvvm 來為我處理絕大多數。
然后我開始創建一個非常簡單的應用程序,它只顯示項目讓我學習 MvvM 的基礎知識。 因此我的視圖看起來像這樣......
<UserControl.DataContext>
<viewmodel:DrawingMenuViewModel/>
</UserControl.DataContext>
<StackPanel>
<TextBox Text="{Binding SearchFilter}"/>
<DataGrid x:Name="ContactsResult"
ItemsSource="{Binding DrawingsCollectionView}"
SelectedItem="{Binding SelectedModel}"
AutoGenerateColumns="False" CanUserAddRows="False"
IsReadOnly="True" Height="300">
<DataGrid.Columns>
<DataGridTextColumn Header="DRAWING NO"
Binding="{Binding Path = DNumber}"/>
<DataGridTextColumn Header="DESCRIPTION"
Binding="{Binding Path = Description}"
Width="*"/>
<DataGridTextColumn Header="REV"
Binding="{Binding Path = Revision}"
Width="200"/>
</DataGrid.Columns>
</DataGrid>
<Button Content="Click" Command="{Binding OpenDrawingCommand}"/>
</StackPanel>
然后我開始安裝后端 ViewModel,到目前為止它工作得很好......
public partial class DrawingMenuViewModel : ObservableObject
{
public ObservableCollection<DrawingModel> _Drawings;
[ObservableProperty] ICollectionView drawingsCollectionView;
[ObservableProperty] DrawingModel selectedModel;
[ObservableProperty] string searchFilter = "D";
public DrawingMenuViewModel() => PopulateDatagrid();
#region Populating DataGrid
public void PopulateDatagrid()
{
// Initialize Data into the DataGrid Control
List<DrawingModel> testD = new List<DrawingModel>
{
new DrawingModel { DNumber = "D1294", Description = "Test 1", Revision = "A"},
new DrawingModel { DNumber = "D1295", Description = "Test 2", Revision = "A"},
new DrawingModel { DNumber = "D1296", Description = "Test 3", Revision = "A"},
new DrawingModel { DNumber = "D1297", Description = "Test 4", Revision = "A"},
};
// Hook-up data to view and set filter for search capability
_Drawings = new ObservableCollection<DrawingModel>(testD);
DrawingsCollectionView = CollectionViewSource.GetDefaultView(_Drawings);
DrawingsCollectionView.Filter = FilterDatagrid;
}
private bool FilterDatagrid(object obj)
{
if (obj is DrawingModel d)
{
return d.DNumber.Contains(searchFilter, StringComparison.OrdinalIgnoreCase) ||
d.Description.Contains(searchFilter, StringComparison.OrdinalIgnoreCase) ||
d.Revision.Contains(searchFilter, StringComparison.OrdinalIgnoreCase);
}
return false;
}
#endregion
[ICommand]
async Task OpenDrawing()
{
if (SelectedModel != null)
{
MessageBox.Show(SelectedModel.DNumber);
}
}
}
我的問題開始於我正在努力理解如何從 SearchFilter 文本框中裝配諸如 TextChanged 事件之類的事件,該事件將運行命令以使用以下語句過濾 datagridview...
CollectionViewSource.GetDefaultView(DrawingsCollectionView).Refresh();
我沒有成功的嘗試是這樣的......
<TextBox Text="{Binding SearchFilter}" TextChanged="{Binding OpenDrawingCommand}"/>
這會導致錯誤 XLS0523“事件‘TextChanged’只能綁定到委托類型‘TextChangedEventHandler’的屬性。”。 所以我試圖嘗試像這樣調用事件......
XAML
<TextBox Text="{Binding SearchFilter}" TextChanged="{Binding OpenDrawing}"/>
C#
public void OpenDrawing(object sender, TextChangedEventArgs e)
{
CollectionViewSource.GetDefaultView(DrawingsCollectionView).Refresh();
}
導致以下錯誤...
System.Windows.Markup.XamlParseException: ''在 'System.Windows.Data.Binding' 上提供值引發了異常。' 行號“15”和行位置“48”。
一種解決方案是使用為此目的而生成的部分方法。
當您將ObservableProperty
應用於字段時,通常會生成以下內容。
您可以在Project>Dependencies>Analyzers>CommunityToolkit.Mvvm.SourceGenerators
項目節點中查看此內容。
public string SearchFilter
{
get => searchFilter;
set
{
if (!EqualityComparer<string>.Default.Equals(searchFilter, value))
{
OnSearchFilterChanging(value);
OnPropertyChanging(new PropertyChangedEventArgs(nameof(SearchFilter)));
searchFilter = value;
OnSearchFilterChanged(value);
OnPropertyChanged(new PropertyChangedEventArgs(nameof(SearchFilter)));
}
}
}
partial void OnSearchFilterChanging(string value);
partial void OnSearchFilterChanged(string value);
您可以在此處了解有關部分方法的更多信息,但 TLDR 是由您決定實現,但也不需要您實現它。
您需要做的就是實現該方法,它將在屬性更改之前和之后調用這些部分方法。
如果您鍵入partial
then space,您將獲得對部分方法的智能感知,就像您鍵入override
時一樣。
partial void OnSearchFilterChanged(string value)
{
DrawingsCollectionView.Refresh();
}
您可能還想更新您的文本框綁定以更具響應性(但不是太)。
<TextBox Text="{Binding SearchFilter, UpdateSourceTrigger=PropertyChanged, Delay=250}"/>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.