2010-09-05 91 views
1

后,我曾与WPF-的TabControl所选择的项目,可以用下面简单的代码被复制了一个问题:WPF的TabControl的SelectedItem重置窗口已经关闭

如果创建了一个新的TabItem,并通过点击选择 - 第二个窗口中的按钮事件,选项卡被创建,添加和选择。当第二个窗口关闭时,选项卡控件的选定项目重置为最后选择的项目。这个问题发生在我的MVVM-app中,它独立于Items-collection。我可以使用ItemsSource或Items-Collection,它总是发生。

有人知道这里发生了什么,或有一个很好的解决方法?

TabControl tabControl = new TabControl() ; 
tabControl.Items.Add(new TabItem { Header="InitialTabItem"}); 
((TabItem)tabControl.Items[0]).Focus(); 
Window mainWindow = new Window() { Content=tabControl,Title="TabControl-Window"}; 
mainWindow.Show();    
Button addButton = new Button() { Content="AddTabItem"}; 
addButton.Click += (o, e) => { 
     TabItem newTabItem=new TabItem(){Header=DateTime.Now.ToLongTimeString()}; 
     tabControl.Items.Add(newTabItem);     
     tabControl.SelectedItem = newTabItem;     
}; 
Window directorWindow = new Window() { Owner = mainWindow ,Content=addButton,Height=80,Width=200,Title="DirectorWindow"}; 
directorWindow.Show(); 

更新

这似乎是一如既往,当我有更大的问题与WPF,是一个问题与focus-management。如果我更改创建代码如下,它的工作原理:

TabItem newTabItem=new TabItem(){Header=DateTime.Now.ToLongTimeString()}; 
tabControl.Items.Add(newTabItem);      
Dispatcher.BeginInvoke(new Action(delegate{ 
    newTabItem.Focus(); 
    tabControl.SelectedItem = newTabItem; 
}), System.Windows.Threading.DispatcherPriority.Input, null); 

但它看起来不是很自信地对我。一些想法?

+0

您是否真的使用MVVM模式?因为你正在创建所有这些标签uisng代码。为什么不考虑使用绑定到TabControl的ItemSource属性的可观察集合, – TalentTuner 2010-09-05 17:25:24

+0

@saurabh:它的演示代码来重现错误。真正的应用程序与ViewModel一起工作,该ViewModel提供了Tab项的ItemsSource以及SelectedTabItem属性。但我不喜欢张贴大量的代码示例。没有人喜欢研究巨大的代码块来看到一个简单的问题。正如我写的,如果我使用Items或ItemsSource属性没有区别。这是一个普遍的问题,可以通过上面的代码进行复制。 – HCL 2010-09-05 17:29:30

回答

1

是的,TabControl有时会表现奇怪。在我们的项目中,我们必须创建一个子类并重写一些方法来解决其中的另一个错误。

在你的情况,似乎一切,如果你专注于TabControl本身工作聚焦TabItem前:

 var tabControl = new TabControl(); 
     var tabItem = new TabItem { Header = "InitialTabItem" }; 
     tabControl.Items.Add(tabItem); 
     tabControl.Focus(); 
     tabItem.Focus(); 
     Window mainWindow = new Window() { Content = tabControl, Title = "TabControl-Window" }; 
     mainWindow.Show(); 
     Button addButton = new Button() { Content = "AddTabItem" }; 
     addButton.Click += (o, args) => 
     { 
      TabItem newTabItem = new TabItem() { Header = DateTime.Now.ToLongTimeString() }; 
      tabControl.Items.Add(newTabItem); 
      tabControl.SelectedItem = newTabItem; 
     }; 
     Window directorWindow = new Window() { Owner = mainWindow, Content = addButton, Height = 80, Width = 200, Title = "DirectorWindow" }; 
     directorWindow.Show(); 

更新1.看评论 - 原代码会导致不良的副作用。

 var tabControl = new TabControl(); 
     var tabItem = new TabItem { Header = "InitialTabItem" }; 
     tabControl.Items.Add(tabItem); 
     Window mainWindow = new Window() { Content = tabControl, Title = "TabControl-Window" }; 
     mainWindow.Show(); 
     tabControl.Focus(); 
     tabItem.Focus(); 
     Button addButton = new Button() { Content = "AddTabItem" }; 
     addButton.Click += (o, args) => 
     { 
      TabItem newTabItem = new TabItem() { Header = DateTime.Now.ToLongTimeString() }; 
      tabControl.Items.Add(newTabItem); 
      tabControl.SelectedItem = newTabItem; 
     }; 
     Window directorWindow = new Window() { Owner = mainWindow, Content = addButton, Height = 80, Width = 200, Title = "DirectorWindow" }; 
     directorWindow.Show(); 
+0

+1你说得对,在我的演示项目中这确实有帮助。我会稍后在真实应用程序中尝试(我必须先完成其他任务)。你知道它为什么这样吗? – HCL 2010-09-05 14:02:50

+0

我想,因为没有人在微软证实了这种情况,并且Focus()本身的逻辑如此复杂,所以没有人能够通过代码审查验证其对所有可能情况的正确性? – 2010-09-05 14:44:26

+0

@Yacoder:坏消息。我在真实应用程序中测试了解决方法 - 它解决了主要问题,但是在关闭窗口后,焦点管理变得疯狂。其中一个结果是TreeViewItems不再可选。看来我在这里发现了一个重大问题。非常感谢您的回答。是一个好的解决方案。我会寻找另一种解决方法。 – HCL 2010-09-05 19:23:10

1

请参阅使用演示代码解决问题的Yacoders解决方案。然而,引导这个解决方案专注于我的真实项目。

似乎对我有用的一种方式就是我在更新中显示的方式。如果有人遇到同样的问题,请尝试下面的代码。到目前为止,我还没有看到任何副作用。

TabControl tabControl = new TabControl() ; 
tabControl.Items.Add(new TabItem { Header="InitialTabItem"}); 
((TabItem)tabControl.Items[0]).Focus(); 
Window mainWindow = new Window() { Content=tabControl,Title="TabControl-Window"}; 
mainWindow.Show();    
Button addButton = new Button() { Content="AddTabItem"}; 
addButton.Click += (o, e) => { 
    TabItem newTabItem=new TabItem(){Header=DateTime.Now.ToLongTimeString()}; 
    tabControl.Items.Add(newTabItem);      
    Dispatcher.BeginInvoke(new Action(delegate{ 
     newTabItem.Focus(); 
     tabControl.SelectedItem = newTabItem; 
    }), System.Windows.Threading.DispatcherPriority.Input, null); 
}; 
Window directorWindow = new Window() { Owner = mainWindow ,Content=addButton,Height=80,Width=200,Title="DirectorWindow"}; 
directorWindow.Show();