WPF FAQ - ItemsControl

How do I access the ItemsPresenter of a ListBox?

This same logic can be used to access the ItemsPresenter of other ItemsControls like ListView, etc.

[C#]
public partial class RetrieveItemsPanelDemo : Window
{
    public RetrieveItemsPanelDemo()
    {
        InitializeComponent();
        ListBox listBox = new ListBox() { ItemsSource = Enumerable.Range(0, 10) };
        this.Content = listBox;
        listBox.Loaded += delegate
        {
            VirtualizingStackPanel itemsPanel = listBox.GetVisualChild<virtualizingstackpanel>();
            if (itemsPanel != null && itemsPanel.IsItemsHost)
            {
                itemsPanel.PreviewMouseLeftButtonDown += delegate { MessageBox.Show('WPF'); };
            }
        };
    }
}

public static T GetVisualChild<t>(this Visual referenceVisual) where T : Visual
{
    Visual child = null;
    for (Int32 i = 0; i < VisualTreeHelper.GetChildrenCount(referenceVisual); i++)
    {
        child = VisualTreeHelper.GetChild(referenceVisual, i) as Visual;
        if (child != null && (child.GetType() == typeof(T)))
        {
            break;
        }
        else if (child != null)
        {
            child = GetVisualChild<t>(child);
            if (child != null && (child.GetType() == typeof(T)))
            {
                break;
            }
        }
    }
    return child as T;
}

</t></t></virtualizingstackpanel>
Permalink
How do I filter out duplicate entries in my list when bound to a data source?

The fact that you have duplicate entries probably suggests that you are binding to the wrong data source. But, in any case, there are possibly valid scenarios where this is necessary. Here is a solution.

One way is to group the list by name using CollectionViewSource and then bind the Groups to the ListBox. Here is some code:

(for better code formatting, look at this thread: Distinct Value Filter For ListBox

If you Contracts collection is like this:

[C#]
public class Contracts : List    
    {   
        public Contracts()   
        {   
            this.Add(new Contract() { ContractKey = '1', Name = 'John' });   
            this.Add(new Contract() { ContractKey = '2', Name = 'Bill' });   
            this.Add(new Contract() { ContractKey = '3', Name = 'Bill' });   
        }   
    }   
  
    public class Contract   
    {   
        public string ContractKey { get; set; }   
        public string Name { get; set; }   
    }

Then you can use the CollectionViewSource to bind to it and group the colelction by Name as follows:

[XAML]

This will render the listbox the way you want – ignoring the duplicate names. You can then interpret the selected item as follows:

[XAML]
private void lb_SelectionChanged(object sender, SelectionChangedEventArgs e)   
        {   
            CollectionViewGroup groupSelected = ((CollectionViewGroup)e.AddedItems[0]);   
            string name = groupSelected.Name;   
            // These contain the items within the group   
            //groupSelected.Items;   
        }
Permalink
How can I apply a Style to a Menu control on a ToolBar ?

You can apply a menu control style on a toolbar by using the Toolbar.MenustyleKey Property. This can be done with the following code snippet,

[XAML]
  <window.resources>
        <style x:key="{x:Static ToolBar.MenuStyleKey}" targettype="Menu">
            <Setter Property='FontSize' Value='14'/>
            <Setter Property='FontStyle' Value='Oblique'/>
            <Setter Property='FontWeight' Value='Bold'/>
            <Setter Property='Background' Value='AliceBlue'/>
        </style>
   </window.resources>
 
<grid>
   <toolbar>
            <menu>
                <menuitem header="File">
                    <menuitem header="New">
                        <menuitem header="Project">
                        <menuitem header="File">
                    </menuitem>
                </menuitem>
            </menuitem></menuitem></menu>
        </toolbar>
</grid>
Permalink