WPF 动态选项卡控件选择更改了错误
本文关键字:错误 选择 控件 动态 选项 WPF | 更新日期: 2023-09-27 18:34:28
我正在使用 MVVM 模式使用 C# 和 WPF 创建一个简单的应用程序。有一个带有几个按钮的主窗口和一个包含视图模型列表的 ContentControl,其中一个是 SearchViewModel。按钮在视图模型之间翻转。
SearchViewModel 绑定到 SearchView 并包含一个 TabControl。属性绑定到 SearchTabViewModel 的列表。在 SearchViewModel 的构造函数中,我正在初始化 SearchTabViewModel 的 ObservableCollection,然后添加两个选项卡。第一个选项卡的标题为"+",另一个选项卡是普通搜索选项卡。TabControl 的 SelectionChanged 事件绑定到检查是否单击了"+"选项卡的方法。如果是,则在"+"选项卡之前插入一个新选项卡,并且 TabControl 的 SelectedIndex 属性设置为插入的选项卡的索引。相当简单的设置。
我遇到的问题是,当应用程序首次运行时,您可以单击"+"选项卡并插入一个新选项卡,但随后"+"选项卡已失效,单击它时没有任何反应。事件不会触发。我已经检查过并且 SelectedIndex 设置为它前面的选项卡,因此它不是选定的选项卡。要修复它,您必须先单击另一个选项卡,然后一切正常。它只是在开始时冻结一次。
任何人都可以看到问题可能是什么吗?我包括代码的相关部分:
XAML
<TabControl
Name="searchTabControl" ItemsSource="{Binding Path=SearchTabs}"
SelectedIndex="{Binding Path=SelectedTabIndex}"
ItemTemplateSelector="{Binding Source={StaticResource searchTabTemplateSelector}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged" >
<i:InvokeCommandAction
CommandName="searchTabHasChanged" Command="{Binding SelectionChangedCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=CommandName}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
....more code
搜索视图模型
public class SearchViewModel : ObservableObject, IPageViewModel
{
#region Fields
public ObservableCollection<SearchTabViewModel> SearchTabs { get; set; }
private int _selectedTabIndex;
private ICommand _selectionChangedCommand;
#endregion
public SearchViewModel()
{
try
{
// initialize the SearchTabs array
this.SearchTabs = new ObservableCollection<SearchTabViewModel>();
// add a tabItem with + in header
SearchTabViewModel tabAdd = new SearchTabViewModel("+");
this.SearchTabs.Add(tabAdd);
// add first tab
AddTabItem();
SelectedTabIndex = 0;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
#region Properties/Commands
public int SelectedTabIndex
{
get { return _selectedTabIndex; }
set
{
_selectedTabIndex = value;
OnPropertyChanged("SelectedTabIndex");
}
}
public ICommand SelectionChangedCommand
{
get
{
if (_selectionChangedCommand == null)
{
_selectionChangedCommand = new RelayCommand(
param => TabSelectionChanged(param)
);
}
return _selectionChangedCommand;
}
}
#endregion
#region Methods
public void TabSelectionChanged(Object source)
{
if (source.ToString() == "searchTabHasChanged")
{
SearchTabViewModel tab = this.SearchTabs[SelectedTabIndex];
if (tab != null && tab.Header != null)
{
if (tab.Header.Equals("+"))
{
// add new tab
SearchTabViewModel addedTab = AddTabItem();
// select newly added tab item
SelectedTabIndex = this.SearchTabs.IndexOf(addedTab);
}
}
}
}
private SearchTabViewModel AddTabItem()
{
int count = SearchTabs.Count;
// create new tab item
SearchTabViewModel tab = new SearchTabViewModel();
tab.Header = string.Format("Tab {0}", count);
// insert tab item right before the last (+) tab item
this.SearchTabs.Insert(count - 1, tab);
return tab;
}
#endregion
}
另外,我注意到的另一个奇怪的行为是,当您第一次运行应用程序并单击"+"选项卡一次以添加新选项卡并且"+"选项卡死亡时,如果应用程序失去焦点并再次获得焦点,SelectionChanged 事件将触发并添加新选项卡?仅当"+"选项卡失效时,才会发生此行为。通过单击另一个选项卡修复它后,此行为将消失。
在 TabSelectionChanged 中,您可以添加一个新的 TabItem 并紧接着更改 SelectedTabIndex。问题是在视图中生成新 TabItem 的 ItemContainerGenerator 尚未触发。这是在数据绑定阶段完成的。因此,当您设置SelectedTabIndex时,您实际上将其设置为(已选择(+选项卡。
若要解决此问题,请通过调用优先级低于 DataBinding 的调度程序上的调用来推迟 SelectedTabIndex 的更改。
this.Dispatcher.BeginInvoke(() => SelectedTabIndex = this.SearchTabs.IndexOf(addedTab), DispatcherPriority.Background);