切换选项卡后 WPF ComboBox 选择更改 [英] WPF ComboBox selection change after switching tabs

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

问题描述

我基于嵌套选项卡制作了一个项目.嵌套选项卡是同一个 viemModel 和同一个 UI 的不同实例.当我在选项卡之间切换时,选项卡中的组合框会根据失去焦点的选项卡进行选择.

I made a project based on nested tabs. the nested tabs are different instance of the same viemModel and the same UI. when I switch between the tabs he comboboxes present in the tabs chenge thei selection depending on the tab that is loosing focus.

我添加了我的测试项目的视图模型和视图.预先感谢您的帮助

I add both the viewmodels and the view of my test project. thank you in advance for your help

主窗口

<Window.Resources>

    <DataTemplate DataType="{x:Type local:IntermediateViewModel}">
        <local:IntermediateView />
    </DataTemplate>

    <DataTemplate x:Key="HeaderedTabItemTemplate">
        <Grid>
            <ContentPresenter
                        Content="{Binding Path=Header, UpdateSourceTrigger=PropertyChanged}" 
                        VerticalAlignment="Center" >
            </ContentPresenter>
        </Grid>
    </DataTemplate>

    <Style x:Key="SimpleTabItemStyle" TargetType="TabItem">
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TabItem}">
                    <Grid>
                        <Border Name="Border" BorderThickness="1" BorderBrush="#555959">
                            <ContentPresenter x:Name="ContentSite" VerticalAlignment="Center" HorizontalAlignment="Center"
                                 ContentSource="Header" Margin="12,2,12,2" RecognizesAccessKey="True" Height ="40" MinWidth ="90"/>
                        </Border>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter TargetName="Border" Property="Background" Value="#555959" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <DataTemplate x:Key="DefaultTabControlTemplate">
        <TabControl IsSynchronizedWithCurrentItem="True" 
                        BorderThickness="0" 
                        ItemsSource="{Binding}" 
                        ItemTemplate="{StaticResource HeaderedTabItemTemplate}"
                        ItemContainerStyle="{StaticResource SimpleTabItemStyle}"
                        SelectionChanged="TabControl_SelectionChanged"
                        />
    </DataTemplate>


    <!---->


</Window.Resources>

<Grid MinHeight="200" MinWidth="300">
    <Grid.RowDefinitions>
        <RowDefinition Height="260*" />
        <RowDefinition Height="51*" />
    </Grid.RowDefinitions>
    <Border >
        <ContentControl 
            Content="{Binding Path=Workspaces}" 
            ContentTemplate="{DynamicResource DefaultTabControlTemplate}"
             />
    </Border>
    <Button Grid.Row="1" Content="Add" Command="{Binding AddCommand}"/>
</Grid>

查看模型(每次创建不同的实例)

view model (create a different istance each time)

class MainWindowViewModel : WorkspacesViewModel<IntermediateViewModel>
{
    public MainWindowViewModel()
    {
        this.WorkspacesView.CurrentChanged += new EventHandler(WorkspacesView_CurrentChanged);
    }

    void WorkspacesView_CurrentChanged(object sender, EventArgs e)
    {
    }

    RelayCommand myVar = null;
    public ICommand AddCommand
    {
        get 
        {
            return myVar ?? (myVar = new RelayCommand(param => 
            {
                SetWindow(new IntermediateViewModel("AA" + this.Workspaces.Count) );
            })); 
        }
    }

一级标签

    <UserControl.Resources>

    <DataTemplate DataType="{x:Type local:ClassViewModel}">
        <local:ClassView />
    </DataTemplate>
</UserControl.Resources>

<Border>
    <ContentControl Content="{Binding Path=CurrentWorkspace, Mode=OneWay}" Loaded="ContentControl_Loaded" DataContextChanged="ContentControl_DataContextChanged" IsVisibleChanged="ContentControl_IsVisibleChanged" LayoutUpdated="ContentControl_LayoutUpdated" TargetUpdated="ContentControl_TargetUpdated" Unloaded="ContentControl_Unloaded" />
</Border>

一级视图模型

类中间视图模型:工作区视图模型{公共字符串标题{获取;放;}

class IntermediateViewModel : WorkspacesViewModel { public string Header { get; set; }

    public IntermediateViewModel(string header)
    {
        Header = header;
        SetWindow(new ClassViewModel(header));
    }
}

嵌套标签

    <UserControl.Resources>
    <CollectionViewSource x:Key="StatusView" Source="{Binding Path=StatusList}"/>
</UserControl.Resources>
<Grid>
    <ComboBox Name="_spl2Status" ItemsSource="{Binding Source={StaticResource StatusView}}"
      SelectedValue="{Binding Path=MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
      SelectedValuePath="FL_TYPE"
      DisplayMemberPath="ID_TYPE" Margin="76,12,0,0" Height="40" VerticalAlignment="Top" HorizontalAlignment="Left" Width="146"
               DataContextChanged="_spl2Status_DataContextChanged"
               IsVisibleChanged="_spl2Status_IsVisibleChanged"
               Loaded="_spl2Status_Loaded"
                SelectionChanged="_spl2Status_SelectionChanged"
               >
    </ComboBox>
</Grid>

嵌套选项卡视图模型

public enum myTypes
{ 
    tipo0 = 0,
    tipo1 = 1,
    tipo2 = 2,
}

class ClassViewModel : WorkspaceViewModel
{
    public ClassViewModel(string name)
    {
        Name = name;
    }

    public string Name { get; set; }

    private List<IntEnumType> _statusList = null;
    public List<IntEnumType> StatusList
    {
        get
        {
            if (_statusList == null)
                _statusList = new List<IntEnumType>()
                {
                    new IntEnumType((int)myTypes.tipo0, myTypes.tipo0.ToString()),
                    new IntEnumType((int)myTypes.tipo1, myTypes.tipo1.ToString()),
                    new IntEnumType((int)myTypes.tipo2, myTypes.tipo2.ToString()),
                };
            return _statusList;
        }
    }

    private int myVar = 1;
    public int MyProperty
    {
        get 
        {
            return myVar; 
        }
        set 
        {
            if (myVar != value)
            {
                myVar = value;
                OnPropertyChanged(() => MyProperty);
            }
        }
    }
}

public class TabItemStyleSelector : StyleSelector
{
    public Style MainTabItem { get; set; }
    public Style ChildrenTabItem { get; set; }
    public Style SpecificationTabItem { get; set; }

    public override Style SelectStyle(object item, DependencyObject container)
    {
        //if (item is IHome)
        //    return MainTabItem;
        //else if (item is SpecificationItemViewModel)
        //    return SpecificationTabItem;
        //else
            return ChildrenTabItem;
    }
}

推荐答案

这有点晚了,但因为我面临同样的问题,所以我想分享我的分析.

Well this is a bit late, but as I'm facing the same issue, I want to share my analysis.

当您更改选项卡时,您将当前选项卡的 DataContext 更改为其他 ViewModel,因此也将 ComboBox 的 ItemsSource 更改为.

When you change your tabs, you change the DataContext of the current Tab to your other ViewModel and hence also the ItemsSource of your ComboBox.

如果您之前选择的项目 (SelectedItem) 不包含在新的 ItemsSource 中,ComboBox 会触发 SelectionChanged-Event,因此将 SelectedIndex 设置为 -1.

In case your previously selected Item (SelectedItem) is not contained within the new ItemsSource, the ComboBox fires a SelectionChanged-Event and therefore sets the SelectedIndex to -1.

尽管 ComboBox 的这种默认行为可能有道理,但在许多情况下非常烦人.

Altough this default behaviour of the ComboBox might make sense, it's very annoying in many cases.

我们已经从 ComboBox 派生了一个自己的类来处理它.但这并不是很令人满意,因为您失去了一些您最可能需要的默认行为.

We've derived an own class from ComboBox, handling that. But it's not very satisfying as you loose some default behaviour you most probably need.

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

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