在 WPF 中开始时绑定所有选项卡项视图模型
Posted
技术标签:
【中文标题】在 WPF 中开始时绑定所有选项卡项视图模型【英文标题】:Bind all Tab item view model at start in WPF 【发布时间】:2014-08-25 03:51:27 【问题描述】:我有一个带有 2 个选项卡的应用程序,它们是带有 MVVM 的 WPF 中的 Person 和 User Management。现在的问题是,当我点击 Person Mag 选项卡 时,PersonViewModel 将绑定到 Person Mag View 和 User Mag em> 和上面提到的情况一样。
如何使 Person 和 User Mag tab 在应用程序启动时绑定其视图模型(两者同时为自己的视图绑定视图模型)而不是绑定单击该选项卡时的视图模型。
XAML
<DockPanel LastChildFill="True">
<TabControl TabStripPlacement="Left" DockPanel.Dock="Left" Margin="5">
<TabItem Width="190" Margin="1">
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="/Images/Person-Management-Icon.png" Width="32" Height="32" />
<TextBlock Text="Person Mangement" Margin="5,0,0,0" VerticalAlignment="Center" />
</StackPanel>
</TabItem.Header>
<TabItem.ContentTemplate>
<DataTemplate>
<ptab:PersonManagementView />
</DataTemplate>
</TabItem.ContentTemplate>
</TabItem>
<TabItem Margin="1">
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="/Images/User-Management-Icon.png" Width="32" Height="32" />
<TextBlock Text="User Mangement" Margin="5,0,0,0" VerticalAlignment="Center" />
</StackPanel>
</TabItem.Header>
<TabItem.ContentTemplate>
<DataTemplate>
<ptab:UserManagementView />
</DataTemplate>
</TabItem.ContentTemplate>
</TabItem>
</TabControl>
</DockPanel>
PersonManagement XAML
<!--View Model Section-->
<UserControl.DataContext>
<vm:PersonViewModel />
</UserControl.DataContext>
<!--End View Model Section-->
<!--Resources Section-->
<UserControl.Resources>
<ResourceDictionary Source="../Resources/ResourceDictionary.xaml" />
</UserControl.Resources>
<!--End Resources Section-->
<DockPanel Name="Person_Management_View">
<TabControl DockPanel.Dock="Top">
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="/Images/Person-Creation-Icon.png" Width="24" Height="24" />
<TextBlock Text="Person Creation" Margin="5,0,0,0" VerticalAlignment="Center" />
</StackPanel>
</TabItem.Header>
<Grid>
<Grid.RowDefinitions>
<!--Name-->
<RowDefinition Height="Auto" />
<!--Gender-->
<RowDefinition Height="Auto" />
<!--Department-->
<RowDefinition Height="Auto" />
<!--Error Message-->
<RowDefinition Height="25" />
<!--Save Button-->
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!--Name Section-->
<Label Grid.Row="0" Grid.Column="0" Content="Name"/>
<Label Grid.Row="0" Grid.Column="1" Content=":"/>
<TextBox Name="txtPersonName" Grid.Row="0" Grid.Column="2" Margin="4">
<TextBox.Text>
<Binding Path="PersonObject.Name" UpdateSourceTrigger="PropertyChanged" >
<Binding.ValidationRules>
<r:PersonNameRule ValidatesOnTargetUpdated="True" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<!--End Name Section-->
<!--Gender Section-->
<Label Grid.Row="1" Grid.Column="0" Content="Gender"/>
<Label Grid.Row="1" Grid.Column="1" Content=":"/>
<ComboBox Grid.Row="1" Grid.Column="2" Margin="4" ItemsSource="Binding GenderList" SelectedItem="Binding PersonObject.Gender"/>
<!--End Gender Section-->
<!--Department Section-->
<Label Grid.Row="2" Grid.Column="0" Content="Department" />
<Label Grid.Row="2" Grid.Column="1" Content=":"/>
<ComboBox Grid.Row="2" Grid.Column="2" Margin="4" ItemsSource="Binding DepartmentList" SelectedItem="Binding PersonObject.DepartmentName" />
<!--End Department Section-->
<!--Error Message Section-->
<TextBlock Grid.Row="3" Grid.Column="2" Margin="4,4,4,0" Visibility="Binding ElementName=txtPersonName, Path=(Validation.Errors), Converter=StaticResource toVisibilityConverter" Style="StaticResource RedTextBlock">
<TextBlock.Text>
<Binding ElementName="txtPersonName" Path="(Validation.Errors).CurrentItem.ErrorContent"/>
</TextBlock.Text>
</TextBlock>
<!--End Error Message Section-->
<!--Save Button Section-->
<Button Grid.Row="4" Grid.Column="2" HorizontalAlignment="Right" MinWidth="100" Margin="4,0,4,4" Content="Save" Command="Binding CreatePersonCommand">
<Button.Style>
<Style TargetType="x:Type Button">
<Setter Property="IsEnabled" Value="false" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="Binding ElementName=txtPersonName, Path=(Validation.HasError)" Value="false" />
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="true" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<!--End Save Button Section-->
</Grid>
</TabItem>
</TabControl>
<!--Person Data Section-->
<DataGrid Name="PersonDataGrid" DockPanel.Dock="Bottom" AutoGenerateColumns="False" IsReadOnly="True" SelectionMode="Single" ColumnWidth="*" ItemsSource="Binding PersonList">
<DataGrid.Columns>
<DataGridTextColumn Header="Id" Binding="Binding PersonID" />
<DataGridTextColumn Header="Name" Binding="Binding Name" />
<DataGridTextColumn Header="Gender" Binding="Binding Gender, Converter=StaticResource emptyStringConverter" />
<DataGridTextColumn Header="Department" Binding="Binding DepartmentName, Converter=StaticResource emptyStringConverter" />
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button IsEnabled="Binding Selected, Converter=StaticResource oppositeBoolConverter" Command="Binding DataContext.DeletePersonCommand, RelativeSource=RelativeSource AncestorType=x:Type DataGrid" CommandParameter="Binding PersonID" Style="StaticResource TransparentButton">
<Image Source="Binding Selected, Converter=StaticResource deleteImageConverter" Width="16" Height="16"/>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Command="Binding DataContext.ViewPersonCommand, RelativeSource=RelativeSource AncestorType=x:Type DataGrid" CommandParameter="Binding PersonID" Style="StaticResource TransparentButton">
<Image Source="/Images/Update-Icon.png" Width="16" Height="16"/>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<!--End Person Data Section-->
</DockPanel>
【问题讨论】:
贴出绑定数据的代码 @user1219310 嗨,请告诉我们,为什么在用户管理选项卡上时需要加载人员视图模型。 Navigation through Views @Sajeetharan 我用于绑定的 XAML 代码 @Eldho erm,因为我有剪贴板功能,当我单击复制到剪贴板按钮时,将复制人员和用户详细信息。 因此,我需要 Person 和 User 选项卡在应用程序首次启动时绑定他们自己的视图模型 【参考方案1】:试试这个
将 Loaded 事件添加到 TabControl
<TabControl TabStripPlacement="Left" DockPanel.Dock="Left" Margin="5" Loaded="Tab_OnLoaded" >
从 xaml 中删除 ContentTemplate 并在代码中分配内容,例如
void Tab_OnLoaded(object sender, RoutedEventArgs e)
var tabControl = sender as TabControl;
if (tabControl != null)
for (int i = 0; i < tabControl.Items.Count; i++)
if (i == 1)
(tabControl.Items[i] as TabItem).Content = new UserControl2();//Here assign the Usercontrol that you want to set as Content
tabControl.Loaded -= Tab_OnLoaded; // Do this on first time only
我不认为这是一个好方法。我希望这会有所帮助。
【讨论】:
以上是关于在 WPF 中开始时绑定所有选项卡项视图模型的主要内容,如果未能解决你的问题,请参考以下文章
使用Android ViewPager2在回收器视图中滚动到底部时自动更改选项卡项