WPF - 将DataGrid ItemsSource绑定到通过单击不同DataGrid中的元素创建的CollectionViewSource

时间:2014-11-01 12:52:02

标签: c# wpf xaml mvvm 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>

1 个答案:

答案 0 :(得分:1)

你有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);