1

Here is my firt question for Stackoverflow, I hope that will be ok!

I'm working on a custom Dropdown Button in WPF, and I would like to add a click event on the buttons "Text1" and "Text2". I have to put this dropdown button in a DLL so I use the WPF CustomControl library. So in the perfect world, I would like to create several methods in the MainWindow.xaml.cs and send the name of the method in a class where the name of the button, the icon , the tooltip, ... that will be used in the generic.xaml to find the method to call.

I hope what I said is clear :3

The purpose of this is to have a reusable dropdown button where I can add some click event in the items when we click on it.

Here is the generic.xaml with my dropdown button :

<Style TargetType="{x:Type local:ButtonDropdown}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:ButtonDropdown}">
                    <mah:DropDownButton Content="{Binding Path=Text, RelativeSource={RelativeSource TemplatedParent}}" 
                                ToolTip="{Binding Path=ToolTip, RelativeSource={RelativeSource TemplatedParent}}"
                                x:Name="DropDownButton"
                                Orientation="Vertical"
                                BorderThickness="0"
                                ItemsSource="{Binding ItemsSource}">
                        <mah:DropDownButton.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal" Margin="0" ToolTip="{Binding Tooltip}">
                                    <StackPanel.InputBindings>
                                        <MouseBinding Command="{Binding Path=SomeCommand, RelativeSource={RelativeSource TemplatedParent}}" MouseAction="LeftClick" />
                                    </StackPanel.InputBindings>
                                    <Image Source="{Binding Icon}" Width="16"></Image>
                                    <TextBlock Text="{Binding Text}" x:Name="PART_DropdownButton">
                                    </TextBlock>
                                </StackPanel>
                            </DataTemplate>
                        </mah:DropDownButton.ItemTemplate>
                        <mah:DropDownButton.Icon>
                            <Image Source="{Binding Path=Icon, RelativeSource={RelativeSource TemplatedParent}}" Width="32"></Image>
                        </mah:DropDownButton.Icon>
                    </mah:DropDownButton>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

The call of this custom dropdown in the MainWindow.xaml :

<CustomButton:ButtonDropdown Text="Dropdown"
                                         x:Name="ButtonDropdown"
                                         Icon="Images/Open.png"
                                         ToolTip="TOOLTIP DROPDOWN"
                                         ItemsSource="{Binding Items}"/>

Here is my method OnApplyTemplate I add the line 'TextBlock textblock= GetTemplateChild("PART_DropdownButton") as TextBlock;' after the first answer.

public override void OnApplyTemplate()
        {
            DropDownButton dropDownButton = GetTemplateChild("DropDownButton") as DropDownButton;
            TextBlock textblock= GetTemplateChild("PART_DropdownButton") as TextBlock;

            textblock.MouseDown += Method1;

            dropDownButton.ItemsSource = DropdownItems;
            dropDownButton.Click += ButtonDropdown_Click;
        }

And finally the class I have created for items in the dropdown :

public class DropdownItem
    {
        private string text;
        private string icon;
        private string tooltip;
        private string clickEvent;
    }

For the moment I have try with command and mousedown on textblock but don't work :/

Edit : I add the name for the textBlock and I add my method OnApplyTemplate from my ButtonDropdown.cs. The dropDownButton.click is ok but when I try to get the "PART_DropdownButton" that is null. I think because of there is not only one but several textBlock so he don't know which one to take. But that is my problem how to asign a different method on all textblock.mouseDown ? How can we put a different name on all textblock ?

2
  • You could put the textblock you're clicking in a button and bind it's command. Re template a button as a textblock or use a button template is just a transparent border. Commented Jul 30, 2020 at 17:08
  • Hi @Andy, thanks for your comment. The problem is not really to add a command or a click event but to know which item in the list of items is clicked. if there is only one item it's easy but I don't know how to get the item selected. Commented Jul 31, 2020 at 7:25

2 Answers 2

1

Assuming your Dropdown Button derives from a button control give the DropDown button a name in the xaml file e.g. "PART_DropdownButton". Then reference the name in the code behind in the OnApplyTemplate procedure. Here you can add an event handler trapping your mouse events.

    private DropdownButton dropdownbutton  = null;
    ...
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        dropdownbutton = base.GetTemplateChild("PART_DropdownButton") as ToggleButton;
        if (dropdownbutton != null)
        {
            dropdownbutton.MouseDown += MouseDown_Click;

        }
        else
            ....;
    }

Next write your event handler for MouseDown_Click.

Regards Martin

Sign up to request clarification or add additional context in comments.

2 Comments

Good response, I would just show the sample XML markup showing how you add the name for the "PART_DropdownButton" context. They already have an x:name context and I think that is what you are referring to, but also I would expand option to show you can also attach to the icon or text as well.
Hi kmcontact and thank you for your answer. I edit my post because I think I don t explain correctly something. I already have a click event for my dropdown and I'm looking how to add a mousedown on the items in my dropdown in my exemple in the textblock. But I don't how much items I will have so this is very hard to find how to add an event. I hope my comment will help you for understanding what I'm looking for. Thanks in advance.
1

I finally find something that works like I want ! I add an Icommand in my dropdownItem. That will contain my method.

public class DropdownItem
{
    private string text;
    private string icon;
    private string tooltip;
    private string clickEvent;
    public ICommand ClickCommand { get; set; }
}

In my MainWindow.xaml.cs I add the command I need.

private ICommand _command1;
    private ICommand _command2;

    public MainWindow()
    {
        InitializeComponent();

        Items.Add(new DropdownItem("Text1", "Images/Open.png", "Method1", "TEST")
        {
            ClickCommand = Command1
        });
        Items.Add(new DropdownItem("Text2", "Images/Open.png", "method2", "TEST2")
        {
            ClickCommand = Command2
        });
        ButtonDropdown.DropdownItems = Items;
    }

    public ICommand Command1
    {
        get
        {
               return _command1 = new RelayCommand(Method1);
        }
    }

    public ICommand Command2
    {
        get
        {
            return _command2 = new RelayCommand(Method2);
        }
    }

    public void Method1()
    {
        MessageBox.Show("Method 1");
    }

    public void Method2()
    {
        MessageBox.Show("Method 2");
    }

And finally I add the call to this method in my generic.xaml

<MouseBinding Command="{Binding ClickCommand}" MouseAction="LeftClick" />

Thanks for your help, that's because of your comments and answers that I understood that I was looking in the bad direction

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.