1

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!!!

Firdavs Kurbonov
  • 1,252
  • 4
  • 16
  • 42

2 Answers2

1

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.

khurshed_nosirov
  • 248
  • 4
  • 20
0

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.

Abe Heidebrecht
  • 30,090
  • 7
  • 62
  • 66
  • I could not figure out how to implement it in my code. Please help me – Firdavs Kurbonov Mar 27 '13 at 10:44
  • The code is working but this is not what I want. Let me explain you what I am doing, I have tab items let's say sell tab items. In each sell tab item I am checking DataGrid Items Count if it is >0 I am returning back to Stock. In your code it is returning only last one(sell tab item), but previous tab items(it may have more than one sell tab item) is getting lost(not returning to my stock. – Firdavs Kurbonov Mar 27 '13 at 13:19
  • This code works in my sample application. Perhaps your FindChild is not working correctly? I am using the answer from http://stackoverflow.com/questions/636383/wpf-ways-to-find-controls. – Abe Heidebrecht Mar 27 '13 at 13:56
  • It is not doing what I am expecting sir. It is just closing all tab items without checking DataGrid Items. – Firdavs Kurbonov Mar 27 '13 at 14:10
  • Well, I see the problem. The removal of the TabItem is happening outside the if block. I updated the answer to show when that happens. – Abe Heidebrecht Mar 27 '13 at 14:24