如何为控件模板中的按钮添加“点击”处理程序?

4


I have a control template: (1)

<Style x:Key="customItemStyle">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <ToggleButton>
                    <Grid Width="260" Height="58">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="58"/>
                            <ColumnDefinition Width="202"/>
                        </Grid.ColumnDefinitions>
                        <Image Grid.Column="0" Source="{StaticResource image_resourse}"/>
                        <Button Grid.Column="1"> Button text </Button>
                    </Grid>
                </ToggleButton>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

它用于像这样自定义ListBoxItems:

(2)
<ListBox>
    ...
    <ListBoxItem Style="{StaticResource customItemStyle}">
    ...
</ListBox

我想在样式被应用到ListBoxItem时,设置位于模板中的Button的“Click”处理程序。 (1) - 样式文件代码 (2) - 某些组件定义文件代码
我该如何做到这一点?

4
你可以使用命令绑定吗? - ken2k
模板是在同一XAML文件中还是其他地方定义为资源的? - Rohit Vats
我正在考虑使用命令绑定重写它,但我想先尝试这种方法。 - Informhunter
2个回答

3
这个做法是在模板上定义一个 ICommand 。这样,就可以毫无问题地将处理程序绑定到所需的代码上。
首先,通过创建子类ListBoxItem来实现,包括“ICommand”依赖属性。
public class CommandListBoxItem : ListBoxItem 
{
    public static readonly DependencyProperty ButtonCommandProperty = 
        DependencyProperty.Register("ButtonCommand", typeof(ICommand), typeof(CommandListBoxItem), null);
    public bool ButtonCommand
    {
        get { return (ICommand)GetValue(ButtonCommandProperty); }
        set { SetValue(ButtonCommandProperty, value); }
    }

    public CommandListBoxItem()
    {
        DefaultStyleKey = typeof(CommandListBoxItem);
    }
}

现在修改控件模板,将命令链接到按钮点击事件上:
<Style x:Key="customItemStyle">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type custom:CommandListBoxItem}">
                <ToggleButton>
                    <Grid Width="260" Height="58">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="58"/>
                            <ColumnDefinition Width="202"/>
                        </Grid.ColumnDefinitions>
                        <Image Grid.Column="0" Source="{StaticResource image_resourse}"/>
                        <Button Grid.Column="1" Command="{TemplateBinding ButtonCommand}"> Button text </Button>
                    </Grid>
                </ToggleButton>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

最后,将command属性绑定到视图模型(或代码后台)中的命令:

<ListBox>
    ...
    <custom:CommandListBoxItem Style="{StaticResource customItemStyle}" 
                               ButtonCommand="{Binding CommandFromViewModel}" />
    ...
</ListBox>

有没有办法直接设置“click”?我只想要像这样的代码:<BoxItem style.template.button.click="button1_click"/>。 - Informhunter
@Informhunter 嗯...是的,如果控件模板在定义处理程序方法的页面/控件上。但是听起来你不想这样做--也就是说,你的控件模板在多个页面之间共享。那么问题就变成了如何将点击处理程序传递给控件模板。从你的问题中没有足够的细节来确定最佳方法。使用ICommand是一种标准且方便的方法。 - McGarnagle
在“ControlTemplate”中,我不得不使用以下代码 Command="{Binding RelativeSource={RelativeSource TemplatedParent}, ButtonCommand}" ,而不是 Command="{TemplateBinding ButtonCommand}" - 除此之外这个方案对我有效。 - 537mfb

0

你需要进行轻微的变化来应用样式。可以处理 Button_Click 事件。

<Window.Resources>
        <Style x:Key="{x:Type ListBoxItem}" TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <ToggleButton>
                            <Grid Width="260" Height="58">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="58"/>
                                    <ColumnDefinition Width="202"/>
                                </Grid.ColumnDefinitions>
                                <Image Grid.Column="0" Source="{StaticResource image_resourse}"/>
                                <Button Grid.Column="1" Click="Button_Click">Button text</Button>
                            </Grid>
                        </ToggleButton>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

<Grid>       
        <ListBox >
            <ListBoxItem>0ABC</ListBoxItem>
            <ListBoxItem>1ABC</ListBoxItem>
            <ListBoxItem>2ABC</ListBoxItem>
        </ListBox>
</Grid>

在 xaml.cs 文件中,可以处理按钮点击事件。

private void Button_Click(object sender, RoutedEventArgs e)
 {
    MessageBox.Show("E hoooo");
 }

1
我想为不同的项目添加不同的处理程序,并且我希望在定义项目时立即添加它们。无论如何,感谢您的回答。 - Informhunter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接