【问题标题】:Filtering one datagrid based on the selected row of another根据另一个数据网格的选定行过滤一个数据网格
【发布时间】:2012-10-13 17:10:43
【问题描述】:

在多年的 WinForms 之后,我开始涉足 WPF,但我正在努力处理数据绑定/过滤。

编辑:这是我的代码;网格 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)
        {

        }
    }
}

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    我会将您的 ViewModel 中的一个属性绑定到您希望从中获取更新 ID 的 DataGrid 的 SelectedItem 属性。然后,您可以在视图的代码隐藏中使用 SelectionChanged 事件,或者使用绑定到 SelectedItem 的属性的设置器来触发对第二个集合的更新。

    另外,确保两个集合都是 ObservableCollection 类型,并且 VideModel 正在实现 INotifyPropertyChanged

    【讨论】:

    • 感谢您的帮助 - 我需要创建一个 ViewModelBase 类并在那里创建绑定属性吗?我想遵循正确的 MVVM 模式,而不是从 Winforms 中汲取坏习惯。我找不到一个明确的例子来说明如何执行我所追求的过滤。
    • 好的。今天晚些时候,我将为您提供一个功能示例。
    • 很棒的东西,这是我积累知识的一个非常好的基础。感谢您的宝贵时间。
    • 还有一点,这是一个关于 MVVM 模式的精彩视频,确实有助于简化要点和目的。我强烈推荐它:blog.lab49.com/archives/2650
    • 六年后,您的视频链接已失效。 ://
    【解决方案2】:

    好的,正如所承诺的,这是一个例子。

    场景:您有 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
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-28
      • 2022-01-03
      • 2017-06-13
      • 2011-09-22
      • 2016-04-16
      • 2014-02-04
      • 1970-01-01
      相关资源
      最近更新 更多