gpt4 book ai didi

WPF:从 ControlTemplate 绑定(bind)到命令

转载 作者:行者123 更新时间:2023-12-03 18:59:14 24 4
gpt4 key购买 nike

我正在尝试向自定义 ListView (MyListView) 添加一个按钮,该按钮触发在 MyListView 中定义的命令 (MyCustomCommand)。我通过应用 ControlTemplate 添加了按钮(和标题文本)。问题是我还没有找到在单击按钮时触发 MyCustomCommand 的方法。我最终想要实现的是打开一个 Popup 或 ContextMenu,我可以在其中选择哪些列应该在 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 的定义:
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:
<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>

注意绑定(bind)到 MyListView 中的 DependencyProperty 的 HeaderTitle。这按预期工作。为什么它与命令的工作方式不同?关于如何使这项工作的任何线索?

最佳答案

您应该首先将命令的包装器属性设为静态并使用

Command={x:Static local:MyListView.MyCustomCommand}

通常,如果命令在每个实例(如 Button)上设置为不同的值,或者类似于 ViewModel 上的 DelegateCommand/RelayCommand,则您只需要 ICommand 属性。您还应该删除 getter 中的所有额外代码,改为内联或在静态构造函数中初始化命令,并在控件的实例构造函数中连接 CommandBinding。
CommandBindings.Add(new CommandBinding(MyCustomCommand, binding_Executed));

* *更新

RoutedCommand 本身应该声明为静态的。 ICommand 实例属性适用于当您的控件的外部使用者传入要执行的命令时,这不是您想要的。这里也不需要 DP,并且您正在使用的 DP 声明不正确 - 为了可用,它们需要具有 GetValue/SetValue 的实例包装器属性。
public static RoutedCommand ShowColumnPickerCommand
{
get; private set;
}

static MyListView()
{
ShowColumnPickerCommand = new RoutedCommand("ShowColumnPickerCommand", typeof(MyListView));
}

关于WPF:从 ControlTemplate 绑定(bind)到命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3871058/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com