WPF:绑定到ControlTemplate的命令 [英] WPF: Bind to command from ControlTemplate

查看:199
本文介绍了WPF:绑定到ControlTemplate的命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图添加一个按钮到自定义ListView(MyListView),它触发在MyListView中定义的命令(MyCustomCommand)。我已经通过应用ControlTemplate添加了按钮(和标题文本)。问题是,我没有找到一种方法来触发MyCustomCommand时点击按钮。我最终想要实现的是打开一个Popup或ContextMenu,我可以选择哪些列应该在ListView中可见。

I am trying to add a button to a custom ListView (MyListView) which triggers a command (MyCustomCommand) defined in MyListView. I have added the button (and a title text) by applying a ControlTemplate. The problem is that I have not found a way to trigger MyCustomCommand when clicking the button. What I eventually want to achieve is to open a Popup or ContextMenu where I can select which columns should be visible in the ListView.

这里是我的模板源:

<Style TargetType="local:MyListView">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:MyListView">
                <Border Name="Border" BorderThickness="1" BorderBrush="Black">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="30" />
                            <RowDefinition />
                        </Grid.RowDefinitions>

                        <Grid Background="LightSteelBlue">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <TextBlock Margin="3,3,3,3" Text="{TemplateBinding HeaderTitle}" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Stretch" FontSize="16" />
                            <Button Margin="3,3,3,3" Grid.Column="1" 
                                    VerticalAlignment="Center" HorizontalAlignment="Right" Height="20"
                                    Command="{TemplateBinding MyCustomCommand}">A button</Button>
                        </Grid>

                        <ScrollViewer Grid.Row="1" Style="{DynamicResource {x:Static GridView.GridViewScrollViewerStyleKey}}">
                            <ItemsPresenter />
                        </ScrollViewer>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这里是MyListView的定义:

Here is the definition for MyListView:

public class MyListView : ListView
{
    public static readonly DependencyProperty MyCustomCommandProperty = 
        DependencyProperty.Register("MyCustomCommand", typeof(ICommand), typeof(MyListView));

    private static RoutedCommand myCustomCommand;

    public ICommand MyCustomCommand
    {
        get
        {
            if (myCustomCommand == null)
            {
                myCustomCommand = new RoutedCommand("MyCustomCommand", typeof(MyListView));

                var binding = new CommandBinding();
                binding.Command = myCustomCommand;
                binding.Executed += binding_Executed;

                CommandManager.RegisterClassCommandBinding(typeof(MyListView), binding);
            }
            return myCustomCommand;
        }
    }

    private static void binding_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        MessageBox.Show("Command Handled!");
    }


    public static readonly DependencyProperty HeaderTitleProperty =
        DependencyProperty.Register("HeaderTitle", typeof(string), typeof(MyListView));

    public string HeaderTitle { get; set; }
}

这里是创建一个简单的MyListView实例的XAML: p>

And here is the XAML that creates a simple instance of MyListView:

<local:MyListView VerticalAlignment="Top" HeaderTitle="ListView title">
    <ListView.View>
        <GridView>
            <GridViewColumn Width="70" Header="Column 1" />
            <GridViewColumn Width="70" Header="Column 2" />
            <GridViewColumn Width="70" Header="Column 3" />
        </GridView>
    </ListView.View>

    <ListViewItem>1</ListViewItem>
    <ListViewItem>2</ListViewItem>
    <ListViewItem>1</ListViewItem>
    <ListViewItem>2</ListViewItem>
</local:MyListView>

注意HeaderTitle绑定到MyListView中的DependencyProperty。这按预期工作。为什么它不像命令一样工作?任何线索如何使这项工作?

Notice HeaderTitle which is bound to the DependencyProperty in MyListView. This works as expected. Why doesn't it work the same way with commands? Any clues of how to make this work?

推荐答案

我不知道这是否正确的方式做到这一点。在注释中读取源代码有点困难,所以我写这个回复作为回答...

I am not sure if this the correct way to do this. It's a bit difficult to read source code in comments, so I write this reply as an answer...

这里是MyListView +的构造函数绑定方法: / p>

Here is the constructor of MyListView + the command binding methods:

public MyListView()
{        
    showColumnPickerCommand = new RoutedCommand("ShowColumnPickerCommand", typeof(MyListView));

    var binding = new CommandBinding();
    binding.Command = showColumnPickerCommand;
    binding.Executed += ShowColumnPicker;
    binding.CanExecute += ShowColumnPickerCanExecute;

    CommandBindings.Add(binding);
}

private void ShowColumnPicker(object sender, ExecutedRoutedEventArgs e)
{
    MessageBox.Show("Show column picker");          
}

private void ShowColumnPickerCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = true;
}

绑定不是在静态上下文中设置的。唯一静态的是命令的DependencyProperty和命令本身:

The bindings are not set up in a static context. The only things that are static are the DependencyProperty for the command, and the command itself:

public static readonly DependencyProperty ShowColumnPickerCommandProperty =
    DependencyProperty.Register("ShowColumnPickerCommand", typeof(RoutedCommand), typeof(MyListView));

private static RoutedCommand showColumnPickerCommand;

public static RoutedCommand ShowColumnPickerCommand
{
    get
    {
        return showColumnPickerCommand;
    }
}

命令需要是静态的才能绑定它从XAML像这样:

The command needs to be static to able to bind to it from the XAML like this:

<Button Command="{x:Static local:MyListView.ShowColumnPickerCommand}" />

这篇关于WPF:绑定到ControlTemplate的命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆