【问题标题】:WPF ComboBox selection change after switching tabs切换选项卡后 WPF ComboBox 选择更改
【发布时间】:2013-03-10 01:00:00
【问题描述】:

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

我添加了我的测试项目的视图模型和视图。 提前感谢您的帮助

主窗口

<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>

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

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>

一级视图模型

类 IntermediateViewModel : WorkspacesViewModel { 公共字符串标题{获取;放; }

    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;
    }
}

【问题讨论】:

    标签: c# wpf mvvm combobox tabs


    【解决方案1】:

    代码有点难以完全理解,但我猜问题是你的ClassViewModel 只有一个实例,它是存储组合框选择的地方{Binding Path=MyProperty,所以MyProperty 中存储的任何内容都将反映在组合框的所有实例中,无论它们位于何处。

    【讨论】:

    • 不,有 2 个视图模型。如果一个文本框有两个不同的值,它可以工作,问题出在组合框上
    • 那么请发布第二个视图模型。两者都绑定到相同的 SelectedValue 或 SelectedIndex 可以解释这种行为。
    • 还添加了其他视图模型
    • 所以如果你保持绑定不变,只是将组合框更改为文本框,那么每个文本框都保持原来的值?
    • 正是...错误仅与组合有关.. 加载两个不同集合的数据网格工作正常,一切都很好,但组合框
    【解决方案2】:

    这有点晚了,但由于我面临同样的问题,我想分享我的分析。

    当您更改选项卡时,会将当前选项卡的 DataContext 更改为您的其他 ViewModel,从而更改您的 ComboBox 的 ItemsSource。

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

    尽管 ComboBox 的这种默认行为可能有意义,但在许多情况下却很烦人。

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

    【讨论】:

    • @Pille-您的回答有助于理解问题。有什么解决办法吗?
    【解决方案3】:

    问题在于您加载的事件处理程序。

    当您切换标签时,您会卸载一个标签并加载一个新标签。

    我怀疑你将MyComboBox.SelectedIndex 更改为_spl2Status_Loaded

    【讨论】:

      猜你喜欢
      • 2013-03-03
      • 2018-10-05
      • 1970-01-01
      • 2018-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多