[英]Load DataTable to WPF DataGrid MVVM
一段时间以来,我一直试图将我的项目移至 MVVM。
我从数据库中获取了一个数据表:
MainProcess.cs:
public static DataTable CustomersInLiinos = new DataTable();
public static void MergedTable()
{
var t1 = ConnectAndRetriveDatatatableS(); // t1
var t2 = ConnectAndRetriveDatatatableF(); // t2
CustomersInLiinos = t1.Copy();
CustomersInLiinos.Merge(t2);
}
视图模型.cs:
private async Task ExecuteLoadMainTableDataAsync(object commandParameter)
{
if (MainProcess.CheckForVPNInterface())
{
if (MainProcess.CustomersInLiinos != null)
{
this.HasProgress = true;
IEnumerable<Item> resultItems = await LoadMainTableDataAsync();
this.Items = new ObservableCollection<Item>(resultItems);
EnableItemsFiltering();
this.HasProgress = false;
}
}
else
{
throw new VpnInterfaceException("Please, check your VPN connection!");
}
}
在 ViewModel.cs 里面我也有这个:
public Task<DataView> LoadMainTableDataAsync()
{
return Task.Run(() =>
{
MainProcess.MergedTable();
return MainProcess.CustomersInLiinos.DefaultView;
});
}
目前我有一个错误指向await LoadMainTableDataAsync();
:
严重性代码描述项目文件行抑制状态错误 CS0266 无法将类型“System.Data.DataView”隐式转换为“System.Collections.Generic.IEnumerable<Liinos_inspector_FilterTest.Item>”。 存在显式转换(您是否缺少演员表?)
我了解LoadMainTableDataAsync
中存在错误? 我正在将数据加载到 DataView,应该加载到 IEnumerable 吗?
使用这个会更容易吗:
public class JoinedFandS
{
public string YRNRO { get; set; }
public string HAKUNIMI { get; set; }
public string NIMIA { get; set; }
public string NIMIB { get; set; }
}
public static IEnumerable<JoinedFandS> GetMyJoinedResult()
{
var t1 = ConnectAndRetriveDatatatableS(); // t1
var t2 = ConnectAndRetriveDatatatableF(); // t2
var firstTable = ...
var secondTable = ...
var results = firstTable.Concat(secondTable);
return results;
}
编辑:
<Window x:Class="Liinos_inspector_FilterTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Liinos_inspector_FilterTest="clr-namespace:Liinos_inspector_FilterTest"
mc:Ignorable="d"
Title="Liinos database inspector" Height="672" Width="1000" Icon="Images/logo_icon-small.jpg" Background="White" MinWidth="1000">
<Window.DataContext>
<ViewModel />
</Window.DataContext>
严重性代码描述项目文件行抑制状态错误 XLS0414 未找到类型“ViewModel”。 验证您没有缺少程序集引用并且所有引用的程序集都已构建。 Liinos 检查器 FilterTest MainWindow.xaml 11
和
严重性代码说明项目文件行抑制状态错误 XDG0008 Windows Presentation Foundation (WPF) 项目不支持 ViewModel。 Liinos 检查器 FilterTest MainWindow.xaml 11
我应该使用什么来代替 ViewModel?
这是数据类型不匹配。 您不能将DataView
压入集合中。 存储DataTable
而不是DataView
也更实用。 从表中获取视图比从视图中获取表更便宜(以防您稍后需要对DataTable
进行操作)。
修复此错误还需要修复过滤。
DataGrid
可以直接处理DataTable
。
请注意,您必须await
LoadMainTableDataAsync
的返回值。 否则这个方法会过早返回(因为结果是在后台线程中计算的)。 我敢肯定,这部分代码甚至无法编译。 也许这只是示例代码。
此示例还根据新的数据结构调整过滤。 要过滤DataTable.DataView
您必须使用DataView.RowFilter
属性(请参阅表达式语法以获取帮助)。 您需要根据您的要求调整实际的过滤器逻辑:
视图模型.cs
class ViewModel : INotifyPropertyChanged
{
public ICommand LoadMainTableDataCommand => new RelayCommand(async param => ExecuteLoadMainTableDataAsync());
private DataTable mainDataTable;
public DataTable MainDataTable
{
get => this.mainDataTable;
set
{
this.mainDataTable = value;
OnPropertyChanged();
// Set the DataTable filter expression
EnableRowFiltering();
}
}
// Binding source for the first name TextBox
private string firstNameSearchKey;
public string FirstNameSearchKey
{
get => this.firstNameSearchKey;
set
{
this.firstNameSearchKey = value;
OnPropertyChanged();
// Refresh the DataTable filter expression
EnableRowFiltering();
}
}
// Binding source for the last name TextBox
private string lastNameSearchKey;
public string LastNameSearchKey
{
get => this.lastNameSearchKey;
set
{
this.lastNameSearchKey = value;
OnPropertyChanged();
// Refresh the DataTable filter expression
EnableRowFiltering();
}
}
private bool hasProgress;
public bool HasProgress
{
get => this.hasProgress;
set
{
this.hasProgress = value;
OnPropertyChanged();
}
}
public void EnableRowFiltering()
{
// The filter assumes a column 'FirstName' and a column 'LastName' in the DataView.
// The filter expression mimics string.StartsWith.
this.MainDataTable.DefaultView.RowFilter =
$"FirstName LIKE '{this.FirstNameSearchKey}*' " +
$"OR LastName LIKE '{this.LastNameSearchKey}*'";
}
private async Task ExecuteLoadMainTableDataAsync()
{
if (MainProcess.CheckForVPNInterface())
{
if (MainProcess.Customers != null)
{
this.HasProgress = true;
this.MainDataTable = await LoadMainTableDataAsync();
this.HasProgress = false;
}
}
else
{
throw new VpnInterfaceException("Please, check your VPN connection!");
}
}
public async Task<DataTable> LoadMainTableDataAsync()
{
return await Task.Run(() =>
{
MainProcess.MergedTable();
return MainProcess.CustomersInLiinos;
});
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
=> this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
主窗口.xaml
<Window>
<Window.DataContext>
<ViewModel />
</Window.DataContext>
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<StackPanel>
<ProgressBar IsIndeterminate="True"
Visibility="{Binding HasProgress, Converter={StaticResource BooleanToVisibilityConverter}}" />
<Button Command="{Binding LoadMainTableDataCommand}"
Content="Load Data" />
<TextBox Text="{Binding FirstNameSearchKey}" />
<TextBox Text="{Binding LastNameSearchKey}" />
<DataGrid ItemsSource="{Binding MainDataTable}" />
<StackPanel>
</Window>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.