gpt4 book ai didi

c# - 将一个按钮绑定(bind)到 3 个不同的 DataGrids,每个 DataGrids 在 TabControl 中

转载 作者:行者123 更新时间:2023-12-03 10:25:01 25 4
gpt4 key购买 nike

我正在处理一个包含 TabControl 的项目.
在每个 TabItem s 有一个 DataGrid绑定(bind)到 ObservableCollection在我的 View 模型中。
我需要绑定(bind)编辑ButtonDataGrid目前是重点( TabItem 是重点)。
是否有可能在没有多个“硬”编码为一个 DataGrid 的按钮的情况下相当容易地完成此操作?/TabItem并使用 MVVM 模式?
所以基本上这个顺序:TabControl -> 已选TabItem -> DataGrid -> SelectedItem Tabcontrol with Datagrids and Button
示例 XAMLcode(基本上没有样式等的真实格式):

<Button Content="Edit"
Command="{Binding ExecuteEditMessmittelCommand}"
CommandParameter="{Binding ElementName=Messmittel_DataGrid, Path=SelectedItem}">
</Button>

<TabControl>

<TabItem Header="Messmittel">
<DataGrid x:Name="Messmittel_Datagrid"
ItemsSource="{Binding MessmittelDisplayCollection}">
<DataGrid.Columns>
<DataGridTextColumn Header="ID"
Binding="{Binding Path=Benutzer_ID}"

<DataGridTextColumn Header="Seriennummer"
Binding="{Binding Path=Seriennummer}"

<DataGridTextColumn Header="MessmittelArt"
Binding="{Binding Path=Vorname}"
</DataGrid.Columns>
</DataGrid>
</TabItem>

<TabItem Header="Mechanik">
<DataGrid x:Name="Mechanik_Datagrid"
ItemsSource="{Binding MechanikDisplayCollection}">
//here is the datagrid content
</DataGrid>
</TabItem>

<TabItem Header="Prüfhilfsmittel">
<DataGrid x:Name="Pruefhilfsmittel_Datagrid"
ItemsSource="{Binding PruefhilfsmittelDisplayCollection}">
//here is the datagrid content
</DataGrid>
</TabItem>

</TabControl>
查看模型( SetProperty 只是触发 INotifyPropertyChanged 并设置值):
public ObservableCollection<MessmittelModel> MessmittelDisplayCollection
{
get { return DatabaseDisplayModel.MessmittelCollection; }
set { SetProperty(ref DatabaseDisplayModel.MessmittelCollection, value);}
}

public ObservableCollection<MessmittelModel> MechanikDisplayCollection
{
get { return DatabaseDisplayModel.MechanischeMessmittelCollection; }
set { SetProperty(ref DatabaseDisplayModel.MechanischeMessmittelCollection, value); }
}
public ObservableCollection<MessmittelModel> PruefhilfsmittelDisplayCollection
{
get { return DatabaseDisplayModel.PruefhilfsmittelCollection; }
set { SetProperty(ref DatabaseDisplayModel.PruefhilfsmittelCollection, value); }
}
在这种情况下,我认为我的 View 模型并不重要,但如果您需要更多信息,请告诉我,我会提供。

最佳答案

静态 MVVM 变体
我认为你必须分解你的主视图模型。您的主视图模型包含由 TabItems 内的数据网格绑定(bind)的列表。 .这个 View 模型很快就会变得臃肿,并且不能很好地分离 View 和关注点。相反,您应该有一个包含 TabControl 的 View 的主视图模型。以及选项卡控件中每个唯一 View 的单独 View 模型。
在您的示例中,一种 View 模型类型就足够了,因为所有三个选项卡都包含相同的控件,并且仅在 DataGrid 中显示一个列表。 .此 View 模型将公开集合以由 DataGrid 绑定(bind)。和当前选择的属性。您可以通过多种方式分配集合,从外部设置它,例如通过主视图模型,通过构造函数传递集合或为此传递服务。

public class MessmittelViewModel : BindableBase
{
private MessmittelModel _selected;
private ObservableCollection<MessmittelViewModel> _messmittelModels;

// ...constructor, initialization of properties, other properties.

public MessmittelModel Selected
{
get => _selected;
set => SetProperty(ref _selected, value);
}

public ObservableCollection<MessmittelModel> MessmittelDisplayCollection
{
get => _messmittelModels;
set { SetProperty(ref _messmittelModels, value);
}
}
在您的主视图模型中,您可以为每个选项卡公开一个 View 模型属性。
public class MainViewModel: BindableBase
{
private MessmittelViewModel _selectedViewModel;
private MechanischeMessmittel _mechanischeMessmittelViewModel;

// ...contructor, initialize properties, other code.

public MessmittelViewModel SelectedViewModel
{
get => _selectedViewModel;
set => SetProperty(ref _selectedViewModel, value);
}

public MechanischeMessmittelViewModel
{
get => _mechanischeMessmittelViewModel;
private set => SetProperty(ref _mechanischeMessmittelViewModel, value);
}
}
然后在你的 XAML 中绑定(bind) SelectedItemTabControlDataContext s 用于选项卡。
<TabControl SelectedItem="{Binding SelectedViewModel}">
<!-- ...other content. -->
<TabItem Header="Mechanik"
DataContext={Binding MechanischeMessmittelViewModel}">
<DataGrid ItemsSource="{Binding MessmittelDisplayCollection}">
<!-- ...data grid content. -->
</DataGrid>
</TabItem>
</TabControl>
现在您可以将命令参数绑定(bind)到 Selected属性(property)...
<Button Content="Edit"
Command="{Binding ExecuteEditMessmittelCommand}"
CommandParameter="{Binding SelectedViewModel.Selected}"/>
...或访问您的 MainViewModel 中选择的 View 模型并得到它的 Selected项目 list 。
var parameter = SelectedViewModel.Selected;
动态 MVVM 变体
当您考虑创建可能包含不同 View 的附加选项卡时,公开三个静态属性不是很可扩展,因此我将向您展示如何以更动态的方式执行此操作。假设您创建了 MessmittelViewModel如上和 FoobarMessmittelViewModel .创建 ObservableCollection基本类型,例如 MessmittelViewModelBase和以前一样的选定属性。
public class MainViewModel: BindableBase
{
private MessmittelViewModelBase _selectedViewModel;
private ObservableCollection<MessmittelViewModelBase> _messmittelModels;

public MainViewModel()
{
// ...other code.

MessmittelViewModels = new ObservableCollection<MessmittelViewModelBase>();
MessmittelViewModels.Add(new MessmittelViewModel(DatabaseDisplayModel.MessmittelCollection));
// ...add view models for the other tabs.
}

// ...other code.

public MessmittelViewModelBase SelectedViewModel
{
get => _selectedViewModel;
set => SetProperty(ref _selectedViewModel, value);
}

public ObservableCollection<MessmittelViewModelBase> MessmittelViewModels
{
get => _messmittelModels;
set { SetProperty(ref _messmittelModels, value);
}
}
绑定(bind) ItemsSourceMessmittelViewModels收集并创建 DataTemplate表示每个具体 View 模型类型的 View 。
<TabControl ItemsSource="{Binding MessmittelViewModels}">
<TabControl.Resources>
<DataTemplate DataType="{x:Type MessmittelViewModel}">
<DataGrid ItemsSource="{Binding MessmittelDisplayCollection}">
<DataGrid.Columns>
<DataGridTextColumn Header="ID"
Binding="{Binding Path=Benutzer_ID}"
<DataGridTextColumn Header="Seriennummer"
Binding="{Binding Path=Seriennummer}"
<DataGridTextColumn Header="MessmittelArt"
Binding="{Binding Path=Vorname}"
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
<!-- ...other data templates -->
</TabControl.Resources>
</TabControl>
就是这样, TabControl现在将根据其类型为 View 模型集合中的每个项目创建一个适当的 View 。由于现在有不同的类型,您可以通过检查类型在代码中选择命令的参数(甚至可能为此选项卡启用它)。
if (SelectedViewModel is MessmittelViewModel messmittelViewModel)
{
var parameter = messmittelViewModel.Selected;
}
使用转换器的 MVVM 变体
对于您当前的方法,您还可以使用多值转换器仅在 XAML 中解决问题。但是,这也是一个静态变体。此转换器将根据选项卡控件中的选定索引返回一个绑定(bind)值。
public class SelectedIndexBindingConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values[(int)values[0] + 1];
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new InvalidOperationException();
}
}
在 XAML 中,您必须绑定(bind) CommandParameter像这样。
<Window.Resources>
<local:SelectedIndexBindingConverter x:Key="SelectedIndexBindingConverter"/>
</Window.Resources>

<Button Content="Edit"
Command="{Binding CommandTest}">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource SelectedIndexBindingConverter}">
<Binding Path="SelectedIndex" ElementName="MyTabControl"/>
<Binding Path="SelectedItem" ElementName="Messmittel_Datagrid"/>
<Binding Path="SelectedItem" ElementName="Mechanik_Datagrid"/>
<Binding Path="SelectedItem" ElementName="Pruefhilfsmittel_Datagrid"/>
</MultiBinding>
</Button.CommandParameter>
</Button>

<TabControl x:Name="MyTabControl">
<!-- ...tab items as before. -->
</TabControl>
您还可以创建一个转换器来遍历可视化树并获取相应 DataGrid 的选定项, 没有绑定(bind)它,但这会假设一个视觉结构并且这个解决方案更健壮,因为你明确地指定了元素。事实上,这个转换器更灵活,因为它允许您将命令参数绑定(bind)到具有选项卡项中任何属性的任何控件。
请注意,您也可以通过触发器在 XAML 中实现相同的目的,但我认为这会过多地干扰控件的样式,并且可能更难重用。

关于c# - 将一个按钮绑定(bind)到 3 个不同的 DataGrids,每个 DataGrids 在 TabControl 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63668571/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com