在Selectionhandd事件中更改ItemSource在事件处理程序后生效

时间:2018-09-07 13:44:13

标签: c# wpf

更改组合框的选择后,我有一个要绑定到ItemsControl的集合。 我想在SelectionChanged处理程序内访问ItemsControl的VisualTree。但是更改ItemsSource仅在EventHandler之后影响ItemsControl。 此时是否可以访问元素?

private void cbShows_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ComboBox cb = sender as ComboBox;
    if (cb.SelectedItem != null)
    {
        Show selectedShow = (Show)cb.SelectedItem;
        txtShowname.Text = selectedShow.ShowName;

        icHalfHourBlocks.DataContext = selectedShow.HalfHourItems;
        icHalfHourBlocks.ItemsSource = selectedShow.HalfHourItems;

        gridShowGrid.Visibility = Visibility.Visible;

        ////////////////////////////////////////////////
        // At this Time need the rendered visual tree //
        ////////////////////////////////////////////////
    }
}

2 个答案:

答案 0 :(得分:0)

  

...但是更改ItemsSource仅在EventHandler之后影响ItemsControl。此时是否可以访问元素?

设置ItemsSourceVisibility属性后,您可以尝试在事件处理程序中测量和安排控件:

private void cbShows_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ComboBox cb = sender as ComboBox;
    if (cb.SelectedItem != null)
    {
        Show selectedShow = (Show)cb.SelectedItem;
        txtShowname.Text = selectedShow.ShowName;

        icHalfHourBlocks.DataContext = selectedShow.HalfHourItems;
        icHalfHourBlocks.ItemsSource = selectedShow.HalfHourItems;

        gridShowGrid.Visibility = Visibility.Visible;

        ////////////////////////////////////////////////
        // At this Time need the rendered visual tree //
        ////////////////////////////////////////////////
        ic.Measure(new Size(icHalfHourBlocks.ActualWidth, icHalfHourBlocks.ActualHeight));
        ic.Arrange(new Rect(0, 0, icHalfHourBlocks.ActualWidth, icHalfHourBlocks.ActualHeight));
    }
}

答案 1 :(得分:0)

您只需要使用BeginInvoke对调度程序执行操作。现在,我可以访问渲染的可视树,并能够检索搜索到的控件。 现在这是我的代码:

private void cbShows_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ComboBox cb = sender as ComboBox;
    if (cb.SelectedItem != null)
    {
        Show selectedShow = (Show)cb.SelectedItem;
        txtShowname.Text = selectedShow.ShowName;

        icHalfHourBlocks.DataContext = selectedShow.HalfHourItems;
        icHalfHourBlocks.ItemsSource = selectedShow.HalfHourItems;

        gridShowGrid.Visibility = Visibility.Visible;

        ////////////////////////////////////////////////
        Dispatcher.BeginInvoke(new Action(() => 
        {
            IEnumerable<Expander> elements = FindVisualChildren<Expander>(icHalfHourBlocks).Where(x => x.Tag != null && x.Tag.ToString() == "HalfHourBlock");
        }), DispatcherPriority.Render);
        ////////////////////////////////////////////////
    }
}

@RaceRalph感谢您的提示。

更新

我发现此案例有更好的解决方案。方法UpdateLayout()进行可视树更新。

private void cbShows_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ComboBox cb = sender as ComboBox;
    if (cb.SelectedItem != null)
    {
        Show selectedShow = (Show)cb.SelectedItem;
        txtShowname.Text = selectedShow.ShowName;

        icHalfHourBlocks.DataContext = selectedShow.HalfHourItems;
        icHalfHourBlocks.ItemsSource = selectedShow.HalfHourItems;

        IcHalfHourBlocks.UpdateLayout(); // <-- My new solution

        IEnumerable<Expander> elements = FindVisualChildren<Expander>(icHalfHourBlocks)
            .Where(x => x.Tag != null && x.Tag.ToString() == "HalfHourBlock");

        gridShowGrid.Visibility = Visibility.Visible;
    }
}