How to get a WPF toolbar to bind to a collection in my virtual machine without using an extender

I have a WPF window with ToolBar. I have a collection of objects in my virtual machine that I am contacting. They appear as buttons, but they always fall into the extended drop-down section ToolBar. How to make these buttons appear in the standard part ToolBar?

I have the following XAML:

<ToolBarTray Grid.Row="1">
    <ToolBar ItemsSource="{Binding Path=MyList}" >
        <ToolBar.ItemTemplate>
            <DataTemplate  >
                <Button ToolTip="{Binding ButtonName}" 
                        Command="{Binding Path=ButtonCommand}" >
                    <Button.Content>
                        <Image Width="32" Height="32" Source="{Binding ImageSource}"/>
                    </Button.Content>
                </Button>
            </DataTemplate>
        </ToolBar.ItemTemplate>
    </ToolBar>
</ToolBarTray>

I have the following C #:

public List<MyClass> MyList
    {
        get
        {
            return new List<MyClass>
                       {
                           new MyClass{ButtonName="Button1",ImageSource=@"C:\Projects\WpfApplication2\WpfApplication2\Employee.png"},
                           new MyClass{ButtonName="Button2",ImageSource=@"C:\Projects\WpfApplication2\WpfApplication2\Employee.png"},
                           new MyClass{ButtonName="Button3",ImageSource=@"C:\Projects\WpfApplication2\WpfApplication2\Employee.png"},
                           new MyClass{ButtonName="Button4",ImageSource=@"C:\Projects\WpfApplication2\WpfApplication2\Employee.png"},
                       };

        }
    }

This is the visual result:

alt text

+5
source share
3 answers

There is an error on the toolbar, if you resize the window, the problem will disappear.

The solution uses a different control, for example:

public class WorkaroundToolBar : ToolBar
{
    private delegate void IvalidateMeasureJob();

    public override void OnApplyTemplate()
    {
        Dispatcher.BeginInvoke(new IvalidateMeasureJob(InvalidateMeasure), 
                                     DispatcherPriority.Background, null);
        base.OnApplyTemplate();
    }
}

+4

xaml , .

+1

To add to Eduardo's, I had to tweak it a bit, as the source of the element was filled asynchronously, some time after the initial interface was displayed:

public class ToolBar : System.Windows.Controls.ToolBar
{
    public override void OnApplyTemplate ()
    {
        Dispatcher.BeginInvoke ((Action)(InvalidateMeasure), DispatcherPriority.Background, null);
        base.OnApplyTemplate ();
    }
    protected override void OnItemsChanged (NotifyCollectionChangedEventArgs e)
    {
        base.OnItemsChanged (e);
        Dispatcher.BeginInvoke ((Action)(InvalidateMeasure), DispatcherPriority.Background, null);
    }
}

This was enough to catch all the extreme cases and the overflow occurred properly when necessary after a combination of elements.

+1
source

All Articles