WPF 中选项卡控件中的同级用户控件之间的通信



我们有一个带有三个选项卡的选项卡控件。每个选项卡包含两个用户控件 A 和 B。用户控件 A 包含一个数据网格。用户控件 B 包含一个文本框和一个选中的列表框,用于筛选用户控件 A 中的数据网格。在上述方案中,在两个用户控件之间进行通信的最佳方法是什么?我正在使用 MVVM 和 Prism Framework 的事件聚合器。

我的 Viem 模型在每个选项卡如下所示

        User Control A  User Control B
Tab1    ViewModelGrid1  ViemModelGridFilter
Tab2    ViewModelGrid2  ViemModelGridFilter
Tab3    ViewModelGrid3  ViemModelGridFilter

我想使用一个视图模型进行网格过滤。

我从选项卡 1 的 ViemModelGridFilter 发布的事件只能由选项卡 1 的 ViewModelGrid1 订阅。但是现在它被所有三个网格视图模型订阅了。

this._eventAggregator.GetEvent<GridFilterEvent>().Publish(list);

请看下面的演示,其中我正在从搜索文本框中提供的文本中过滤学生集合。Datagrid 和 Textbox,两者都位于不同的用户控件中,并共享相同的数据上下文。

XAML for Datagrid UserControl:

<Grid>
    <DataGrid Name="studentGrid" CanUserAddRows="False" Grid.Row="3" Grid.ColumnSpan="2" AutoGenerateColumns="False" ItemsSource="{Binding Students, Mode=TwoWay}" >
        <DataGrid.Columns>                
            <DataGridTextColumn Header="Student's grade" Binding="{Binding StudentGrade}">
            </DataGridTextColumn>
            <DataGridTextColumn Header="Student's Name" Binding="{Binding StudentName}">
            </DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

XAML 文本框用户控件:

<Grid>
    <TextBox Text="{Binding SearchText,UpdateSourceTrigger=PropertyChanged}"  Height="30" Width="100" HorizontalAlignment="Left"></TextBox>
</Grid>

要放置在选项卡控件中的 XAML:

<StackPanel>
    <local:tb></local:tb>
    <local:dg></local:dg>
</StackPanel>

视图模型:

public class MainWindowViewModel : INotifyPropertyChanged
{
   public MainWindowViewModel()
    {            
        Students = new ObservableCollection<Student>();
        Students.Add(new Student { StudentGrade = 1, StudentName = "Jack" });
        Students.Add(new Student { StudentGrade = 2, StudentName = "Jill" });
        Students.Add(new Student { StudentGrade = 3, StudentName = "Humpty" });
    }
    private string _SearchText;
    //to be used to filer datagrid
    public string SearchText
    {
        get { return _SearchText; }
        set
        {
            _SearchText = value;
            //filter logic, I am filtering on base of student name, you can have your own implementation.
            Students = new ObservableCollection<Student>(Students.Where(x => x.StudentName.ToUpper().Contains(value.ToUpper())).ToList());
            NotifyPropertyChanged("SearchText");
        }
    }        
    private ObservableCollection<Student> _students;
    // to hold list of students
    public ObservableCollection<Student> Students
    {
        get { return _students; }
        set
        {
            _students = value;
            NotifyPropertyChanged("Students");
        }
    }        
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String info)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));
    }
}

以及用于分配 DataContext XAML.cs 文件的代码:

public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new MainWindowViewModel();            
    }  

这种方法是纯 MVVM,可以根据需要进行增强和修改,而不会遇到太多麻烦。

最新更新