经过多年的WinForms之后,我正在将自己的脚趾浸入WPF中,而且我正在努力进行数据绑定/过滤。
编辑:这是我背后的代码; grid 1(companiesDataGrid)SelectionChanged事件是网格2(sitesDataGrid)上的过滤发生的地方。简而言之,当vs_Companies改变位置时,需要过滤vs_Sites; vs_Sites有一个名为Company_ID的字段,它将过滤以匹配当前所选vs_Companies行的ID字段。
这是我对WPF的第一次尝试 - 如果有任何指针作为在多用户环境中连接到SQL服务器的最佳实践,我将不胜感激,这个当前代码是非常基本的CollectionViewSource数据馈送直接到两个没有中间对象的数据网格。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace RevDB
{
public partial class MainWindow : Window
{
public RevDB.TSDBDataSet ds_Rev;
public RevDB.TSDBDataSetTableAdapters.CompaniesTableAdapter ta_Companies;
public RevDB.TSDBDataSetTableAdapters.SitesTableAdapter ta_Sites;
public System.Windows.Data.CollectionViewSource vs_Sites;
public System.Windows.Data.CollectionViewSource vs_Companies;
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded_1(object sender, RoutedEventArgs e)
{
ds_Rev = ((RevDB.TSDBDataSet)(this.FindResource("tsDBDataSet")));
//Sites
ta_Sites = new RevDB.TSDBDataSetTableAdapters.SitesTableAdapter();
ta_Sites.Fill(ds_Rev.Sites);
vs_Sites = ((System.Windows.Data.CollectionViewSource)(this.FindResource("sitesViewSource")));
vs_Sites.View.MoveCurrentToFirst();
//Companies
ta_Companies = new RevDB.TSDBDataSetTableAdapters.CompaniesTableAdapter();
ta_Companies.Fill(ds_Rev.Companies);
vs_Companies = ((System.Windows.Data.CollectionViewSource)(this.FindResource("companiesViewSource")));
vs_Companies.View.MoveCurrentToFirst();
//Data bindings
//this.txt_Company.SetBinding(TextBox.TextProperty, new Binding() { Path = "TargetText", Source = this });
}
private void companiesDataGrid_SelChanged(object sender, SelectionChangedEventArgs e)
{
}
}
}
答案 0 :(得分:0)
我会将ViewModel中的属性绑定到DataGrid的 SelectedItem 属性,您希望从该属性获取更新的ID。然后,您可以在视图的代码隐藏中使用 SelectionChanged 事件,也可以使用绑定到 SelectedItem 的属性的setter来触发对第二个集合的更新。
此外,请确保两个集合的类型为 ObservableCollection ,并且VideModel正在实施 INotifyPropertyChanged 。
答案 1 :(得分:0)
好的,正如所承诺的,这是一个例子。
场景:您有2个DataGrids。一个DataGrid包含公司和其他站点。
条件:每当选择公司时,所选网站都会更改以反映相关公司网站。
实施:MVVM,更改 SelectedCompany 属性会更新ViewModel中的 SelectedSite 属性。
注意:我添加了额外的DataGrid样式,以使Lost-Focus状态可见。默认情况下,所选行在Lost Focus上不可见。
<强>模型强>:
公司
using System;
using System.ComponentModel;
namespace CascadingDataGrids
{
public class Company : INotifyPropertyChanged
{
private int _id;
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>
/// The id.
/// </value>
public int Id
{
get { return _id; }
set
{
if (value != _id)
{
_id = value;
NotifyPropertyChanged("Id");
}
}
}
private string _companyName;
/// <summary>
/// Gets or sets the name of the company.
/// </summary>
/// <value>
/// The name of the company.
/// </value>
public string CompanyName
{
get { return _companyName; }
set
{
{
if (value != _companyName)
{
_companyName = value;
NotifyPropertyChanged("CompanyName");
}
}
}
}
private int _siteId;
/// <summary>
/// Gets or sets the site id.
/// </summary>
/// <value>
/// The site id.
/// </value>
public int SiteId
{
get { return _siteId; }
set
{
if (value != _siteId)
{
_siteId = value;
NotifyPropertyChanged("SiteId");
}
}
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
#endregion
}
}
网站
using System;
using System.ComponentModel;
namespace CascadingDataGrids
{
public class Site : INotifyPropertyChanged
{
private int _id;
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>
/// The id.
/// </value>
public int Id
{
get { return _id; }
set
{
if (value != _id)
{
_id = value;
NotifyPropertyChanged("Id");
}
}
}
private string _siteName;
/// <summary>
/// Gets or sets the name of the site.
/// </summary>
/// <value>
/// The name of the site.
/// </value>
public string SiteName
{
get { return _siteName; }
set
{
{
if (value != _siteName)
{
_siteName = value;
NotifyPropertyChanged("SiteName");
}
}
}
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
#endregion
}
}
<强>视图模型强>:
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
namespace CascadingDataGrids
{
public class DemoViewModel : INotifyPropertyChanged
{
#region Properties
private ObservableCollection<Company> _companies;
/// <summary>
/// Gets or sets the companies.
/// </summary>
/// <value>
/// The companies.
/// </value>
public ObservableCollection<Company> Companies
{
get { return _companies; }
set
{
if (value != _companies)
{
_companies = value;
NotifyPropertyChanged("Companies");
}
}
}
private Company _selectedCompany;
/// <summary>
/// Gets or sets the selected company.
/// </summary>
/// <value>
/// The selected company.
/// </value>
public Company SelectedCompany
{
get { return _selectedCompany; }
set
{
if (value != _selectedCompany)
{
_selectedCompany = value;
NotifyPropertyChanged("SelectedCompany");
// Set Site
var currentSite =
Sites.FirstOrDefault(x => x.Id == SelectedCompany.SiteId);
// Evaluate
if (currentSite != null)
{
SelectedSite = currentSite;
}
}
}
}
private ObservableCollection<Site> _sites;
/// <summary>
/// Gets or sets the sites.
/// </summary>
/// <value>
/// The sites.
/// </value>
public ObservableCollection<Site> Sites
{
get { return _sites; }
set
{
if (value != _sites)
{
_sites = value;
NotifyPropertyChanged("Sites");
}
}
}
private Site _selectedSite;
/// <summary>
/// Gets or sets the selected site.
/// </summary>
/// <value>
/// The selected site.
/// </value>
public Site SelectedSite
{
get { return _selectedSite; }
set
{
if (value != _selectedSite)
{
_selectedSite = value;
NotifyPropertyChanged("SelectedSite");
}
}
}
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="DemoViewModel"/> class.
/// </summary>
public DemoViewModel()
{
// New instances
Companies = new ObservableCollection<Company>();
Sites = new ObservableCollection<Site>();
// Build
BuildCompanies();
BuildSites();
}
#endregion
#region Members
/// <summary>
/// Builds the companies.
/// </summary>
private void BuildCompanies()
{
// Set companies
Companies = new ObservableCollection<Company>
{
new Company { Id = 1, CompanyName = "Microsoft", SiteId = 1 },
new Company { Id = 2, CompanyName = "Google", SiteId = 3 },
new Company { Id = 3, CompanyName = "Amazon", SiteId = 2 },
};
// Set selected to first value
SelectedCompany = Companies.FirstOrDefault();
}
/// <summary>
/// Builds the sites.
/// </summary>
private void BuildSites()
{
// Set sites
Sites = new ObservableCollection<Site>
{
new Site { Id = 1, SiteName = "Redmond, WA" },
new Site { Id = 2, SiteName = "Seattle, WA" },
new Site { Id = 3, SiteName = "Mountain View, CA" }
};
// Set selected to first value
SelectedSite = Sites.FirstOrDefault();
}
#endregion
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
#endregion
}
}
查看:XAML
<Window x:Class="CascadingDataGrids.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Companies and Sites" Height="700" Width="500">
<Window.Resources>
<Style x:Key="Header" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Calibri" />
<Setter Property="FontSize" Value="20" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
<!-- Datagrid -->
<Style TargetType="{x:Type DataGrid}">
<Setter Property="Background" Value="White" />
<Setter Property="CanUserAddRows" Value="False" />
<Setter Property="CanUserResizeRows" Value="False" />
<Setter Property="CanUserDeleteRows" Value="False" />
<Setter Property="SelectionMode" Value="Single" />
<Setter Property="SelectionUnit" Value="FullRow" />
<Setter Property="EnableRowVirtualization" Value="True" />
</Style>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Cursor" Value="Hand" />
<Style.Triggers>
<!-- Hover -->
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1" Opacity="0.5">
<GradientStop Color="#dceef7" Offset="0" />
<GradientStop Color="#f2f9fc" Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<!-- Selected -->
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1" Opacity="1">
<GradientStop Color="#333" Offset="0" />
<GradientStop Color="#333" Offset="0.01" />
<GradientStop Color="#e0e4e7" Offset="0.01" />
<GradientStop Color="#c2dbea" Offset="0.40" />
<GradientStop Color="#c2dbea" Offset="0.60" />
<GradientStop Color="#e0e4e7" Offset="0.99" />
<GradientStop Color="#333" Offset="0.99" />
<GradientStop Color="#333" Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="24" />
<RowDefinition Height="240" />
<RowDefinition Height="40" />
<RowDefinition Height="24" />
<RowDefinition Height="240" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Style="{StaticResource Header}" Text="Companies" />
<DataGrid Grid.Row="1" Margin="0 12 0 0"
ItemsSource="{Binding Path=Companies}"
SelectedItem="{Binding Path=SelectedCompany, Mode=TwoWay}"
RowHeight="20"
IsReadOnly="True" />
<TextBlock Grid.Row="3" Style="{StaticResource Header}" Text="Sites" />
<DataGrid Grid.Row="4" Margin="0 12 0 0"
ItemsSource="{Binding Path=Sites}"
SelectedItem="{Binding Path=SelectedSite, Mode=TwoWay}"
RowHeight="20"
IsReadOnly="True" />
</Grid>
</Window>
查看:代码隐藏
using System.Windows;
namespace CascadingDataGrids
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
#region Members
private readonly DemoViewModel _vm;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="MainWindow"/> class.
/// </summary>
public MainWindow()
{
// Set viewmodel
_vm = new DemoViewModel();
// Set data context
this.DataContext = _vm;
// Initialize UI
InitializeComponent();
}
#endregion
}
}