简体   繁体   中英

How to pass ContentControl Element to CommandParameter?

I have a toolbar that show many Button with Image and TextBlock .

Then, I create a CommandManager to manager all Button 's commands. So, I want to implement a factory to assign action by Button 's TextBlock .

This is my xaml and Command function, I try to pass all Button 's Text , but I don't know how to do.

<StackPanel>
    <StackPanel.Resources>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Command" Value="{Binding ActionCommand}"/>
            <Setter Property="CommandParameter" Value="{Binding Path=Text}"/>
        </Style>
    </StackPanel.Resources>
    <Button>
        <StackPanel>
            <Image Source="/Resources/ToolBar/open.png"/>
            <TextBlock Text="Open"/>
        </StackPanel>
    </Button>
    <Button>
        <StackPanel>
            <Image Source="/Resources/ToolBar/save.png"/>
            <TextBlock Text="Save"/>
        </StackPanel>
    </Button>
</StackPanel>

ActionManager:

public ICommand ActionCommand { get { return new RelayCommand(_onActionCommand); } }

private void _onActionCommand(object parameter)
{
    if (parameter == null)
    {
        return;
    }

    string buttonContent = parameter as string;
    switch (buttonContent)
    {
        case "Open":
            new OpenWindow().ShowDialog();
            break;
        case "Open":
            new Save();
            break;
    }
}

A Button has no concept of "Text" but you could set the Tag property to a string and pass this one:

<StackPanel>
    <StackPanel.Resources>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Command" Value="{Binding ActionCommand}"/>
            <Setter Property="CommandParameter" Value="{Binding Path=Tag, RelativeSource={RelativeSource Self}}"/>
        </Style>
    </StackPanel.Resources>
    <Button Tag="Open">
        <StackPanel>
            <Image Source="/Resources/ToolBar/open.png"/>
            <TextBlock Text="Open"/>
        </StackPanel>
    </Button>
    <Button Tag="Save">
        <StackPanel>
            <Image Source="/Resources/ToolBar/save.png"/>
            <TextBlock Text="Save"/>
        </StackPanel>
    </Button>
</StackPanel>

i would have done this way :

<Button Tag="AnyUniqueString">

and bind the command to it

<Setter Property="CommandParameter" Value="{Binding Path=Tag}"/>

so you are not linked to the text button (u can translate it) - but take care that with one command for all, yo will have trouble manage the refresh and can_execute that will enable/disable your buttons. Perhaps not so complicated to bind each button to separate commands...?

I use it like this in my solution CBR

<StackPanel Margin="10,0,10,0" Orientation="Vertical">
                <Button Style="{DynamicResource CbrStandardButton}" Margin="2,10,2,10"
                        Command="{Binding ForwardCommand}" CommandParameter="CatalogNewCommand" >
                    <DockPanel Margin="10">
                        <Image Source="/CBR;component/Resources/Images/32x32/library_new.png" Width="32"></Image>
                        <Label Style="{DynamicResource CbrLabel}"
                               Content="{LocalizationExtension ResModul=CBR, Key=HomeView.LblActionNew, DefaultValue=Start a new library}" />
                    </DockPanel>
                </Button>
                <Button Style="{DynamicResource CbrStandardButton}" Margin="2,10,2,10"
                        Command="{Binding ForwardCommand}" CommandParameter="BookOpenCommand" >
                    <DockPanel Margin="10">
                        <Image Source="/CBR;component/Resources/Images/32x32/book/book_read.png" Width="32"></Image>
                        <Label Style="{DynamicResource CbrLabel}"
                               Content="{LocalizationExtension ResModul=CBR, Key=HomeView.LblActionRead, DefaultValue=Read a book}" />
                    </DockPanel>
                </Button>
                <Button Style="{DynamicResource CbrStandardButton}" Margin="2,10,2,10"
                        Command="{Binding ForwardCommand}" CommandParameter="SysHelpCommand">
                    <DockPanel Margin="10">
                        <Image Source="/CBR;component/Resources/Images/32x32/book_type/book_type_xps.png" Width="32"></Image>
                        <Label Style="{DynamicResource CbrLabel}"
                               Content ="{LocalizationExtension ResModul=CBR, Key=HomeView.LblActionTutorial, DefaultValue=Quick start tutorial}" />
                    </DockPanel>
                </Button>
            </StackPanel>

you can use this Markup Extension:

https://www.codeproject.com/Articles/456589/Bindable-Converter-Parameter

it allows you to bind command parameter to a xaml property. so you can, for example, put some identifier in the tag field for your button and bind it to the command parameter using the extension. This way you use only one command, only one binding and you get all you need to distinguish buttons in your command handler.

Hope it helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM