简体   繁体   English

tabControl / tabitem刷新困难

[英]Difficulty with tabControl/tabitem refresh

I have a WPF window with a maintabWindow and several tabitems. 我有一个带有maintabWindow的WPF窗口和几个tabitems。 It normally works fine and the layout is this: 它通常工作正常,布局是这样的:

在此输入图像描述

but when I BEFORE add the following window: 但是当我在添加以下窗口时:

在此输入图像描述

the result is this: 结果是这样的:

在此输入图像描述

So the problem is related with the tabControl/tabItem refresh. 所以问题与tabControl / tabItem刷新有关。 This is fairly obvious but even more because if I move the window or pass with the mouse on the a tabItem they get refreshed one by one. 这是相当明显的,但更重要的是因为如果我移动窗口或使用鼠标在tabItem上传递它们会逐个刷新。

I searched and found that here is a solution: http://geekswithblogs.net/NewThingsILearned/archive/2008/08/25/refresh--update-wpf-controls.aspx 我搜索并发现这是一个解决方案: http//geekswithblogs.net/NewThingsILearned/archive/2008/08/25/refresh--update-wpf-controls.aspx

so I added: 所以我补充说:

  this.MainTab.Refresh();
  this.tabItem1.Refresh();
  this.tabItem2.Refresh();
  this.tabItem3.Refresh();
  this.tabItem4.Refresh();
  this.tabItem5.Refresh();

but that didn't change a thing. 但这并没有改变一件事。

Thanx for any help Thanx任何帮助

Ok so in the end it has a quite a weird behavious. 好吧,最后它有一个非常奇怪的行为。 If I do 如果我做

for (int i = 0; i < tbcMain.Items.Count; i++)
  {
    tbcMain.SelectedIndex = i;
    tbcMain.UpdateLayout();
  }

it works. 有用。 But I have to set the 1st tabitem so if I add 但是如果我添加的话,我必须设置第一个tabitem

 tbcMain.SelectedIndex = 0;

it doesn't. 它没有。 So the solution was put a sleep and it works again. 所以解决方案已经睡了,它再次起作用。

for (int i = 0; i < tbcMain.Items.Count; i++)
  {
    tbcMain.SelectedIndex = i;
    tbcMain.UpdateLayout();
  }

  System.Threading.Thread.Sleep(250);
  tbcMain.SelectedIndex = 0;

But that is not elegant at all. 但这根本不优雅。 If anyone has a better solution pls let me know it. 如果有人有更好的解决方案请让我知道。 Btw adding the tbcMain.SelectedIndex = 0; 顺便说一下,添加tbcMain.SelectedIndex = 0; on the loaded event of the mainWindow is of no use. 在mainWindow的加载事件是没有用的。

You should be able to set your SelectedIndex first, and without having to include it in your loop: 您应该能够首先设置SelectedIndex,而不必将其包含在循环中:

tbcMain.SelectedIndex = 0;

Then, basing it off of your response, you should be able to either just do .UpdateLayout() on each of your TabItems: 然后,基于您的响应,您应该能够在每个.UpdateLayout()上执行.UpdateLayout()

MainTab.UpdateLayout();
tabItem1.UpdateLayout();
tabItem2.UpdateLayout();
tabItem3.UpdateLayout();
tabItem4.UpdateLayout();
tabItem5.UpdateLayout();

Or you should be able to do something like this in your loop: 或者你应该能够在你的循环中做这样的事情:

MainTab.UpdateLayout();
for (int i = 0; i < tbcMain.Items.Count; i++)
{
    TabItem tbi = (TabItem)this.FindControl("tabItem"+i);
    tbi.UpdateLayout();
}

Updating/refreshing should have nothing to do with setting the selected one. 更新/刷新应与设置选定的更新/刷新无关。 Including the selection of the tab within the loop to i was your problem - not a race condition . 包括循环中选项卡的选择是i的问题 - 不是竞争条件 Set the tbcMain.SelectedIndex = 0 outside of your loop and you should be fine. 在循环之外设置tbcMain.SelectedIndex = 0 ,你应该没问题。 Sometimes, however, this doesn't work and you need to set it with Dispatcher : 但是,有时这不起作用,您需要使用Dispatcher进行设置:

Dispatcher.BeginInvoke((Action)(() => this.tbcMain.SelectedIndex = 0));

There's a write up/comments on a separate thread regarding why it needs to be sent to Dispatcher : 在单独的线程上有一个关于为什么需要将其发送到Dispatcher注释/注释:

How to programmatically select a TabItem in WPF TabControl 如何以编程方式在WPF TabControl中选择TabItem

Though, unfortunately for me, I had a similar issue where I was trying to refresh a ListView on a subtab. 虽然,不幸的是,我有一个类似的问题,我试图在子选项卡上刷新ListView。 Neither .UpdateLayout() , nor .InvalidateVisual() (as I saw on this thread ) worked. 既没有.UpdateLayout() ,也没有.InvalidateVisual() (就像我在这个线程上看到的那样)。 I just had to rebind my grid in the button event I was using on my main page, so that when the tab was clicked, it was refreshed manually. 我只需要在我的主页面上使用的按钮事件中重新绑定网格,这样当单击选项卡时,它会手动刷新。 I added an x:Name property on the tab so I could call it using "dot" syntax, and it exposed the ListView. 我在选项卡上添加了一个x:Name属性,因此我可以使用“dot”语法调用它,并显示ListView。 I simply added the DataTable of results back to that ListView's DataContext. 我只是将DataTable的结果添加回ListView的DataContext。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM