好的,正如所承诺的,这是一个例子。
场景:您有 2 个 DataGrid。一个 DataGrid 包含公司和其他站点。
条件:只要选择公司,所选网站就会更改以反映相关公司网站。
实现:MVVM,SelectedCompany 属性的更改会更新ViewModel 中的SelectedSite属性。
注意:我添加了额外的 DataGrid 样式以使 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
}
}