Question

I have Tab Control which has many tab items, I am checking Data Grid Items Count while closing tab items. For the first time it works fine(I mean in first iteration). After closing one tab item, in second iteration sellDtg is null. Does anyone know why it is happening? I am concerning that this is UI problem, layout is not being refreshed. Please help me or show direction.

while (tc.HasItems) 
        {
            TabItem ti = tc.SelectedItem as TabItem;
            if (ti.Header == "Продажа") 
            {
                Microsoft.Windows.Controls.DataGrid sellDtg = FindChild<Microsoft.Windows.Controls.DataGrid>(tc, "SellDataGrid");
                if (sellDtg.Items.Count > 0)
                {
                    Sell sl = new Sell();
                    if (Sell.basketfromSellDateListBox == false)
                    {
                        sl.ClearBasket(sellDtg);
                        Sell.ClearFromSellBasket((int)sellDtg.Tag);
                    }
                }
            }
            if (ti != null)
                tc.Items.Remove(ti);

        }

Thanks in advance!!!

Was it helpful?

Solution

I've written a simple FindChildLogical function in analogy for LogicalTreeHelper below:

public static T FindChildLogical<T>(DependencyObject parent, string childName)
           where T : DependencyObject
        {
            if (parent == null) return null;
            var child = LogicalTreeHelper.FindLogicalNode(parent, childName);

            return (T)child;
        }

and you call it as:

Microsoft.Windows.Controls.DataGrid sellDtg = FindChildLogical<Microsoft.Windows.Controls.DataGrid>(ti, "SellDataGrid");

I hope it gets you where you intend to.

OTHER TIPS

I am going to assume your FindChild method uses the VisualTreeHelper to find its children.

In the first iteration, the TabItem's Content has been through a layout pass, and is visible. This means that the TabItem's Content will be in the visual tree.

However, for the other tab items, their Content hasn't been through a layout pass (it is only added to the visual tree when it's parent gets selected, and this has to then go through a layout/render pass), and won't be in the visual tree.

There are a couple of ways to get the child content of a TabItem that hasn't been through a layout pass as the selected tab:

1) You can try using the LogicalTreeHelper to find the Grid you're looking for (and you will likely have to search the Content of the TabItem, not the TabControl).

2) You can take your code out of the while loop, and do a callback on the dispatcher at the Loaded priority:

void RemoveAllItems()
{
    if (!tc.HasItems) return;

    TabItem ti = tc.SelectedItem as TabItem;
    if (ti.Header == "Продажа") 
    {
        var sellDtg = FindChild<Microsoft.Windows.Controls.DataGrid>(tc, "SellDataGrid");
        if (sellDtg.Items.Count > 0)
        {
            Sell sl = new Sell();
            if (Sell.basketfromSellDateListBox == false)
            {
                sl.ClearBasket(sellDtg);
                Sell.ClearFromSellBasket((int)sellDtg.Tag);
            }

            if (ti != null)
                tc.Items.Remove(ti);
        }
    }

    Dispatcher.BeginInvoke(new Action(RemoveAllItems), DispatcherPriority.Loaded);
}

If you use the second method, you will likely be able to see the tab items removed one at a time, which may be something you don't want to see.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top