簡體   English   中英

WPF-將DataGrid ItemsSource綁定到通過單擊其他DataGrid中的元素創建的CollectionViewSource

[英]WPF - Bind DataGrid ItemsSource to a CollectionViewSource created by clicking an element in a different DataGrid

我對WPF還是很陌生-所以請指出您認為我做的不正確的任何事情。

簡而言之,問題是:在ViewModel中,我將一些數據存儲在_Adata變量中,該變量在View中正確顯示為DataGrid表。 用戶可以單擊表的任何行,這將觸發一個將一些數據存儲在_Bdata變量中的操作。 盡管此變量綁定到視圖中的另一個DataGrid,但不會顯示。

現在,這是代碼。

我的MainWindowViewModel類如下所示:

public class MainWindowViewModel : INotifyPropertyChanged
{
    // in the real implementation these are not created on the fly but fetched elsewhere
    private ObservableCollection<A> _Adata;
    public ObservableCollection<A> AData { get { return _Adata; } }

    private ObservableCollection<B> _Bdata;
    public ObservableCollection<B> BData { get { return _Bdata; } }

    public ICollectionView AView, BView;

    private A _currSelectedA;
    public A CurrSelectedA
    {
        get { return _currSelectedA; }
        private set
        {
            _currSelectedA = value;
            OnPropertyChanged("CurrentSelectedA");
        }
    }

    private ICommand _rowClickCommand;

    public MainWindowViewModel()
    {

        _rowClickCommand = new MainWindow.DelegateCommand(() =>
        {
            // This command gets correctly executed, yet it does not produce any visible result in the View
            var complexTypeB = new ComplexTypeB();
            _Bdata = new ObservableCollection<B>(complexTypeB.l);
            BView = CollectionViewSource.GetDefaultView(_Bdata);
        });

        var someComplexTypeInstance = new ComplexTypeA();
        _Adata = new ObservableCollection<A>(someComplexTypeInstance.l);

        AView = CollectionViewSource.GetDefaultView(_Adata);
        // At this point, the UI correctly shows the table

        AView.CurrentChanged += delegate
        {
            _currSelectedA = (A)AView.CurrentItem;
        };
    }

    public ICommand RowClickCommand
    {
        get { return _rowClickCommand; }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

}

我的DataModel包含ViewModel中使用的類的定義:

    public class A { /* ... */ }
    public class B { /* ... */ }

    public class ComplexTypeA
    {
        public List<A> l = new List<A>();
    }
    public class ComplexTypeB
    {
        public List<B> l = new List<B>();
    }

MainWindow類看起來很標准:

public class MainWindow : Window
{
    public MainWindow()
    {
        DataContext = new MainWindowViewModel();
    }

    public class DelegateCommand : ICommand
    {
        private readonly Action _action;
        public DelegateCommand(Action action) { _action = action; }

        public bool CanExecute(object parameter) {return true; }

        public void Execute(object parameter) { _action(); }

        public event EventHandler CanExecuteChanged;
        public void OnCanExecuteChanged()
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }
    }
}

最后是MyWindow.xaml

<Window x:Class="WpfApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:local="clr-namespace:WpfApplication"
        mc:Ignorable="d" 
        d:DesignHeight="300" d:DesignWidth="300"
        Title="MainWindow">
    <Grid d:DataContext="{d:DesignInstance Type=local:MainWindowViewModel}">

        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <Grid Grid.Row="0">
            <DataGrid
            x:Name="ADataGrid"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            SelectedItem="{Binding CurrSelectedA, Mode=TwoWay}"
            ItemsSource="{Binding AData}">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseLeftButtonUp" >
                        <i:InvokeCommandAction
                        Command="{Binding RowClickCommand}"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </DataGrid>
        </Grid>

        <Grid Grid.Row="1">
            <DataGrid
            x:Name="BDataGrid"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            ItemsSource="{Binding BData}"/>
        </Grid>

    </Grid>
</Window>

您有2種方式來實現所需的目標:1。

_rowClickCommand = new MainWindow.DelegateCommand(() =>
    {
        // This command gets correctly executed, yet it does not produce any visible result in the View
        var complexTypeB = new ComplexTypeB();
        _Bdata = new ObservableCollection<B>(complexTypeB.l);
        this.NotifyPropertyChanged("BData"); //you need this because you create a new instance
        BView = CollectionViewSource.GetDefaultView(_Bdata);
    });

或者代替創建一個新的,只需清除並添加

   BData.Clear();
   foreach(var item in complexTypeB.l)
     BData.Add(item);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM