列表的一部分未呈现

时间:2013-12-10 08:06:20

标签: c# .net wpf user-interface

我遇到布局渲染问题。我在C#有一些经验,但我以前从未遇到过这样的事情。

我正在构建视频消息应用程序,当对话开始时,会打开一个新窗口,并在Collapsed上设置列表和背景。 在对话结束时,新窗口关闭,列表和背景设置回Visible。

当发生这种情况时,我得到了这个: enter image description here 我的列表是使用StackPanel和UserControl构建的,当我滚动列表时,渲染再次正常。

我在Google上对有关未在UI上呈现的对象进行了一些研究,发现您可以使用InvalidateVisual强制再次呈现UI,但这似乎不适用于我的应用。在列表和背景可见之后,我在每个对话结束时调用此方法。

有哪些方法可以确保UI正确呈现? 感谢。

更新1:

我已将这段代码添加到UserControl中。

protected override void OnRender(DrawingContext drawingContext)
{
   InvalidateVisual();
   base.OnRender(drawingContext);
}

但这是要走的路吗?我已经看到,当我这样做时,循环调用该方法,但我似乎并没有影响我测试的设备上的性能。

更新2:

经过一些更密集的测试后,我发现我在Update 1中添加的代码对应用程序的性能有很大的影响,所以这对我不起作用。

更新3:

现在我使用InvalidateVisual在调用Timer之前创建了延迟。在调用InvalidateVisual之前将Timer设置为500毫秒,这会强制布局再次渲染。当我的第二个窗口关闭时,布局将第二次更新。这是我的代码

Timer t = new Timer(500);
t.AutoReset = false;
t.Elapsed += (s, ee) =>
{
   ((Timer)s).Stop();
   ((Timer)s).Dispose();
   InvalidateVisual();
};
t.Start();

经过快速测试后似乎可行,但我需要更加强烈地测试以确保。任何其他建议仍然受欢迎。

更新4:

在更新3中测试我的解决方案后,我发现这不起作用。 @Sheridan:我的应用程序不需要重新调整大小,它是一个全屏应用程序。这是我编写的用于创建列表的代码:

这是XAML代码

<TabItem x:Name="TabHistory" Header="Geschiedenis">
  <sys:FixedScrollViewer VerticalAlignment="Stretch" 
                     HorizontalAlignment="Stretch" 
                     PanningMode="VerticalOnly" 
                     Margin="0,0,0,7"
                     HorizontalScrollBarVisibility="Hidden"  
                     VerticalScrollBarVisibility="Hidden"
                     HorizontalContentAlignment="Left">
    <StackPanel x:Name="CallLogList" />
  </sys:FixedScrollViewer>
</TabItem>

这就是填充它的代码。

private void OnRosterUpdate(object sender, RosterUpdateEventArgs e) 
{
  if (MessageWindow.IsOpen) MessageWindow.Close();
  Dispatcher.Invoke((Action)delegate()
  {
     if (e.Action == RosterAction.ADD)
     {
        RosterContact button = new RosterContact(e.Item);
        button.Call += StartCall_Callback;
        button.ShowInfo += Info_Callback;
        button.HideInfo += button_HideInfo;
        roster.Children.Add(button);
     }
     else if (e.Action == RosterAction.REMOVE)
     {
        foreach (RosterContact item in roster.Children)
        {
           if (item.UserData.Peer == e.Item.Peer)
           {
              roster.Children.Remove(item);
              break;
           }
        }
     }
  });
}

RosterContact的类型为UserControl。

2 个答案:

答案 0 :(得分:0)

我不认为这与InvalidateVisual有关...在WPF中,我们不需要手动刷新UI ...如果写得正确,WPF负责刷新UI。

不幸的是,您没有显示任何代码,因此很难确定,但每当我听到/阅读StackPanel并呈现问题时,通常都意味着相同的事情。 ..不要使用StackPanel来进行UI布局!!他们没有调整其内容的大小。尝试用Grid替换它们,你的问题可能就可以解决了。

答案 1 :(得分:0)

我搜索了分配,但没有发现任何事情。所以我按照自己的方式确保列表不会消失在我身上。它可能有点脏,但我不能带来任何其他东西。当然,当找到另一种方式时,建议仍然受到欢迎。

我现在的方法是在屏幕上创建一个完整的白色屏幕。我是这样做的,首先我在我的表单中创建了一个全屏Grid,并给它一个白色背景。

<Grid Background="White" Visibility="Collapsed" x:Name="gridWhite" />

我还创建了一个功能,使白屏可见并在一秒后折叠。

private void ShowWhiteScreen()
{
    Dispatcher.Invoke(() =>
    {
        gridWhite.Visibility = System.Windows.Visibility.Visible;
        Timer t = new Timer(1000);
        t.AutoReset = false;
        t.Elapsed += (s, e) =>
        {
            ((Timer)s).Stop();
            ((Timer)s).Dispose();
            Dispatcher.Invoke(() =>
            {
                gridWhite.Visibility = System.Windows.Visibility.Collapsed;
            });
        };
        t.Start();
    });
}

我通过从另一台平板电脑调用测试平板电脑测试了这一点,在对话后我的错误没有再出现。我在两台设备上进行了5次测试,每次测试结果相同。