根据另一个数据网格的选定行过滤一个数据网格

时间:2012-10-13 17:10:43

标签: c# wpf

经过多年的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)
        {

        }
    }
}

2 个答案:

答案 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
    }
}