2012-01-31 37 views
4

我有一个ItemsControl的在Window列的其中一个包含一个简单的很窄的StackPanel,供应就像一个弹出这是一个目标在某些情况下显示。的ItemsControl不会显示在它弹出后重新渲染

在已经示出并且用户已经被通知有关的东西后,用户关闭通过按钮(绑定到该按钮的命令的手段本弹出只是设置视图模型到弹出的财产。 IsOpen绑定到false)。

弹出关闭,但其图像保持在的ItemsControl印迹,直到它被滚动或另一个窗口重叠它。

如何重绘ItemsControl的弹出后已经关闭?

代码:

1)的ItemsControl

<ScrollViewer ...> 
    <ItemsControl x:Name="ux_List" ItemTemplate="{DynamicResource Lib_ItemTemplate}" ItemsSource="{Binding Path=TemplateInfos,Mode=OneWay}" AlternationCount="2" ... /> 

2)项目模板

<DataTemplate x:Key="Lib_ItemTemplate"> 
    <Grid x:Name="grid"> 
... 
    <StackPanel Grid.Column="1"> 
     <Popup IsOpen="{Binding Path=HasError,Mode=OneWay}"> 
      <ContentPresenter Content="{Binding Path=ErrorContext, Mode=OneWay}" 

,并有在上面的代码段的最后一行演示中关闭按钮:

<Button ... Command="{TemplateBinding CloseButtonCommand}" /> 

的命令被绑定到该按钮,像这样实现的:

private void OnCloseErrorMessageCommand() 
{ 
    HasError = false; 
    ... 
} 
+0

你能张贴你的意思吗?或者也许是一些代码?我认为弹出窗口会绘制在与UI图层不同的层上,因此重绘ItemsControl可能不会执行任何操作。 – Rachel 2012-01-31 14:55:18

+0

我无法重现您的问题。当我关闭弹出窗口时,一切都很好地关闭。 你能告诉我们你的标记吗? 但是,这样的事情应该工作: <弹出关= “myPopup_Closed” ...... 私人无效myPopup_Closed(对象发件人,EventArgs的){ myItemsControl.InvalidateVisual(); } – SvenG 2012-01-31 15:06:56

+0

我从来没有见过一个DataTemplate中的Popup,对我来说它看起来不是一个有效的方法,但我不确定。其他人说什么? – Clemens 2012-01-31 15:33:54

回答

0

当弹出关闭,会发生什么,如果你设置可见=倒塌?看起来好像完全可以从视图中移除它。

否则,我知道没有办法重新呈现单个项目和ItemsControl.Refresh方法将刷新所有项目的(而且通常会显示goofyness(物品消失和再现,动画重置等)。

+0

1)我试图通过数据绑定将Visibility属性设置为Collapsed(与IsOpen一起) - 结果相同 2)我不知道ItemsControl.Refresh()方法。它真的存在吗? – Niccolo 2012-01-31 14:58:31

+0

我知道Listbox.Items.Refresh存在以及其他ItemsControl的化身。它只是告诉Items控件处理绘制的项目,重新查询项目集合并重绘它们。 – CodeWarrior 2012-01-31 15:04:14

+1

可以肯定的是,当您更改IsOpen属性时,* something *在视觉上是正确的?如果没有,您是否实施了INotifyPropertyChanged? – CodeWarrior 2012-01-31 15:05:50

0

很难猜测是什么阻止您的ItemsControl从重绘弹出关闭后,这通常应该不会发生。

你总是可以做

一件事就是打电话InvalidateVisualInvalidateArrange上的ItemsControl,这迫使一个完整的新布局/渲染周期。

+0

重新呈现ItemsControl我向GotFocus事件添加了一个处理程序(在Popup关闭并且承载ItemsControl的窗口获得焦点后执行)。在这个处理程序中,我调用了ItemsControl的UpdateLayout()方法,但Popup的脚印仍然存在。 – Niccolo 2012-01-31 15:04:46

+1

哦,我搞不清楚UpdateLayout和InvalidateVisual并更新了我的答案。谢谢SvenG,并为此感到抱歉。 – Clemens 2012-01-31 15:10:43

+0

我在GotFocus代码隐藏处理程序中尝试了它们:UpdateLayout,InvalidateVisual和InvalidateArrange - 不幸的是他们都没有帮助重新渲染ItemsControl – Niccolo 2012-01-31 15:16:54

2

这里是我workground:

在控制的父窗口:

public IntPtr Hwnd { get; set; } 
    protected override void OnSourceInitialized(EventArgs e) 
    { 
     base.OnSourceInitialized(e); 
     IntPtr hwnd = new WindowInteropHelper(this).Handle; 
     this.Hwnd = hwnd; 
    } 

    public void Refresh() 
    { 
     if (Hwnd == IntPtr.Zero) 
      throw new InvalidOperationException("Hwnd"); 
     InvalidateRect(this.Hwnd, IntPtr.Zero, true); 
    } 

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] 
    public static extern bool InvalidateRect(IntPtr hWnd, IntPtr rect, bool erase); 

弹出关闭后,调用refresh()方法。

+0

我在托管代码中尝试了所有我能想到的内容,但弹出窗口在关闭后未被擦除。这个解决方案,使用本地调用,取得了诀窍。 – ken 2014-06-13 18:48:45

相关问题