0

何年にもわたるWinFormsの後で、私はWPFに足を踏み入れていますが、データのバインド/フィルタリングに苦労しています。

編集:これが私のコードの背後にあります。グリッド1(companiesDataGrid)SelectionChangedイベントは、グリッド2(sitesDataGrid)でのフィルタリングが発生する場所です。つまり、vs_Companiesの位置が変更されたときに、vs_Sitesをフィルタリングする必要があります。vs_SitesにはCompany_IDというフィールドがあり、現在選択されているvs_Companies行のIDフィールドと一致するようにフィルター処理されます。

これはWPFでの私の最初の刺し傷です-マルチユーザー環境でSQLサーバーに接続する際のベストプラクティスとしてのポインターがある場合、この現在のコードは非常に基本的であり、CollectionViewSourceデータが2つに直接フィードされます中間オブジェクトのないデータグリッド。

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)
        {

        }
    }
}
4

2 に答える 2

0

ViewModel のプロパティを、更新された ID を取得する DataGridのSelectedItemプロパティにバインドします。次に、ビューのコード ビハインドでSelectionChangedイベントを使用するか、 SelectedItemにバインドされたプロパティのセッターを使用して、2 番目のコレクションへの更新をトリガーします。

また、両方のコレクションがObservableCollection型であり、VideModel がINotifyPropertyChangedを実装していることを確認してください。

于 2012-10-13T20:09:47.383 に答える
0

約束どおり、例を示します。

シナリオ: 2 つの DataGrid があります。1 つの 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
    }
}
于 2012-10-14T20:01:55.117 に答える