WPF选项卡控件和MVVM选择 [英] WPF tab control and MVVM selection

查看:106
本文介绍了WPF选项卡控件和MVVM选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 MVVM WPF 应用程序.定义如下.

I have a TabControl in an MVVM WPF application. It is defined as follows.

<TabControl Style="{StaticResource PortfolioSelectionTabControl}" SelectedItem="{Binding SelectedParameterTab}" >
    <TabItem Header="Trades" Style="{StaticResource PortfolioSelectionTabItem}">
        <ContentControl Margin="0,10,0,5" Name="NSDetailTradeRegion" cal:RegionManager.RegionName="NSDetailTradeRegion" />
    </TabItem>
    <TabItem Header="Ccy Rates" Style="{StaticResource PortfolioSelectionTabItem}">
        <ContentControl Margin="0,10,0,5" Name="NSDetailCcyRegion" cal:RegionManager.RegionName="NSDetailCcyRegion" />
    </TabItem>
    <TabItem Header="Correlations / Shocks" Style="{StaticResource PortfolioSelectionTabItem}">
        <ContentControl Name="NSDetailCorrelationRegion" cal:RegionManager.RegionName="NSDetailCorrelationRegion" />
    </TabItem>
    <TabItem Header="Facility Overrides" Style="{StaticResource PortfolioSelectionTabItem}" IsEnabled="False">
        <ContentControl Name="NSDetailFacilityOverrides" cal:RegionManager.RegionName="NSDetailFacilityOverrides" />
    </TabItem>
</TabControl>

因此,每个选项卡项目的内容都有与其相关联的自己的视图.这些视图均具有 MEF [Export]属性,并通过视图发现与相关区域相关联,因此上面的代码就是我需要加载选项卡控件并在它们之间进行切换的全部操作.它们都引用了它们后面的同一个共享ViewModel对象,因此都可以无缝交互.

So each tab item content has its own view associated with it. Each of those views has the MEF [Export] attribute and is associated with the relevant region through view discovery, so the above code is all I need to have the tab control load and switch between them. They all reference the same shared ViewModel object behind them and so all interact seamlessly.

我的问题是,当用户导航到父窗口时,我希望选项卡控件默认为第二个选项卡项.通过在XAML IsSelected="True"中在TabItem 2号中指定,在第一次加载窗口时,这样做很容易.当用户离开屏幕然后返回到屏幕时,这样做不那么容易.

My problem is that when the user navigates to the parent window, I want the tab control to default to the second tab item. That is easy enough to do when the window is first loaded, by specifying in XAML IsSelected="True" in TabItem number 2. It is less easy to do when the user navigates away from the screen and then comes back to it.

我考虑过在选项卡控件上具有SelectedItem={Binding SelectedTabItem}属性,因此我可以通过编程方式在ViewModel中设置选定的选项卡,但是问题是我不知道ViewModel中的TabItem对象,因为它们在上文中已声明.仅XAML,因此我没有TabItem对象可传递给setter属性.

I thought about having a SelectedItem={Binding SelectedTabItem} property on the tab control, so I could programmatically set the selected tab in the ViewModel, but the problem is I have no knowledge of the TabItem objects in the ViewModel as they are declared above in the XAML only, so I have no TabItem object to pass to the setter property.

我的一个想法是使子视图(构成上面每个选项卡项目的内容)在XAML的UserControl级别上具有一种样式,如下所示.

One idea I had was to make the child Views (that form the content of each of the tab items above) have a style on the UserControl level of their XAML, something along the following.

<Style TargetType={x:Type UserControl}>
    <Style.Triggers>
        <DataTrigger Property="IsSelected" Value="True">
             <Setter Property="{ElementName={FindAncestor, Parent, typeof(TabItem)}, Path=IsSelected", Value="True" />
        </DataTrigger>
    </Style.Triggers>
</Style>

我知道findancestor位不正确;我只是将其放在此处以指定我的意图,但是我不确定确切的语法.基本上每个UserControl都有一个触发器来监听ViewModel上的一个属性(不确定我如何区分每个不同的UserControl,因为显然他们不能全部监听相同的属性,或者当该属性设置为时它们会同时选择)是的,但是为每个用户控件都有一个属性似乎很难看),然后找到其父TabItem容器并将IsSelected值设置为true.

I know the findancestor bit isn't correct; I've just put it there to specify my intent, but I am not sure of the exact syntax. Basically for each UserControl to have a trigger that listens to a property on the ViewModel (not sure how I would distinguish each different UserControl as obviously they can't all listen to the same property or they would all select simultaneously when the property is set to True, but having a property for each usercontrol seems ugly) and then finds its parent TabItem container and sets the IsSelected value to true.

我在正确的位置上有解决方案吗?是否可以做我正在考虑的事情?有更整洁的解决方案吗?

Am I on the right track with a solution here? Is it possible to do what I am pondering? Is there a tidier solution?

推荐答案

如果您查看

If you look at the TabControl Class page on MSDN, you'll find a property called SelectedIndex which is an int. Therefore, simply add an int property into your view model and Bind it to the TabControl.SelectedIndex property and then you can select whichever tab you like at any time from the view model:

<TabControl SelectedIndex="{Binding SelectedIndex}">
    ...
</TabControl>


更新>>>


UPDATE >>>

使用此方法设置启动"标签更为简单:

Setting a 'startup' tab is even easier using this method:

在视图模型中:

private int selectedIndex = 2; // Set the field to whichever tab you want to start on

public int SelectedIndex { get; set; } // Implement INotifyPropertyChanged here

这篇关于WPF选项卡控件和MVVM选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆