wpf tabControl/tabitem 刷新困难

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33974939/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:34:08  来源:igfitidea点击:

Difficulty with tabControl/tabitem refresh

c#wpfrefreshtabcontrol

提问by Patrick

I have a WPF window with a maintabWindow and several tabitems. It normally works fine and the layout is this:

我有一个带有 maintabWindow 和几个 tabitems 的 WPF 窗口。它通常工作正常,布局是这样的:

enter image description here

在此处输入图片说明

but when I BEFORE add the following window:

但是当我之前添加以下窗口时:

enter image description here

在此处输入图片说明

the result is this:

结果是这样的:

enter image description here

在此处输入图片说明

So the problem is related with the tabControl/tabItem refresh. 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.

所以问题与tabControl/tabItem刷新有关。这是相当明显的,但更重要的是,如果我移动窗口或在 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

感谢任何帮助

回答by Patrick

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; on the loaded event of the mainWindow is of no use.

但这一点都不优雅。如果有人有更好的解决方案,请告诉我。顺便说一句,添加 tbcMain.SelectedIndex = 0; 在 mainWindow 的加载事件上是没有用的。

回答by vapcguy

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()对每个 TabItem 执行以下操作:

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 iwas your problem - not a race condition. Set the tbcMain.SelectedIndex = 0outside of your loop and you should be fine. Sometimes, however, this doesn't work and you need to set it with Dispatcher:

更新/刷新应该与设置选定的无关。在循环中包括选项卡的选择i是您的问题 - 不是竞争条件。设置tbcMain.SelectedIndex = 0循环的外部,你应该没问题。但是,有时这不起作用,您需要将其设置为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. Neither .UpdateLayout(), nor .InvalidateVisual()(as I saw on this thread) worked. 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:Nameproperty on the tab so I could call it using "dot" syntax, and it exposed the ListView. I simply added the DataTable of results back to that ListView's DataContext.

但是,不幸的是,我遇到了类似的问题,我试图刷新子选项卡上的 ListView。都没有.UpdateLayout(),也没有.InvalidateVisual()(正如我在这个线程上看到的)工作。我只需要在我在主页上使用的按钮事件中重新绑定我的网格,以便在单击选项卡时手动刷新它。我x:Name在选项卡上添加了一个属性,以便我可以使用“点”语法调用它,并且它公开了 ListView。我只是将结果的 DataTable 添加回 ListView 的 DataContext。