使用控件模板中的按钮清除 wpf 列表框选择并且没有代码隐藏 [英] Clear wpf listbox selection using button in control template and no codebehind
问题描述
我想为 WPF ListBox
创建一个 Style
,它在 ControlTemplate
中包含一个 Button
用户可以单击它并清除 ListBox
选择.我不想使用codebehind 以便此Style
可以应用于任何ListBox
.我曾尝试使用 EventTrigger
s 和 Storyboard
s,但事实证明这是有问题的,因为它只在第一次工作并且停止 Storyboard
会重新设置先前的选择.我知道我可以使用用户控件,但我想知道是否可以仅使用 Style
来实现.
I want to create a Style
for a WPF ListBox
that includes a Button
in the ControlTemplate
that the user can click on and it clears the ListBox
selection.
I dont want to use codebehind so that this Style
can be applied to any ListBox
.
I have tried using EventTrigger
s and Storyboard
s and it has proved problematic as it only works first time and stopping the Storyboard
sets the previous selection back.
I know I could use a user control but I want to know if it is possible to achieve this using only a Style
.
推荐答案
使用 XAML 无法实现这一点,只能使用 .NET 框架提供的类.但是,您仍然可以通过定义一个新命令(称为 ClearSelectionCommand
)和一个新的附加属性(称为 ClearSelectionOnCommand
)来生成可重用的解决方案.
It is not possible to achieve this using XAML and only the classes provided by the .NET framework. However you can still produce a reusable solution by defining a new command (call it ClearSelectionCommand
) and a new attached property (call it ClearSelectionOnCommand
).
然后你可以将这些元素融入你的风格中.
Then you can incorporate those elements into your style.
例子:
public class SelectorBehavior
{
public static RoutedCommand
ClearSelectionCommand =
new RoutedCommand(
"ClearSelectionCommand",
typeof(SelectorBehavior));
public static bool GetClearSelectionOnCommand(DependencyObject obj)
{
return (bool)obj.GetValue(ClearSelectionOnCommandProperty);
}
public static void SetClearSelectionOnCommand(
DependencyObject obj,
bool value)
{
obj.SetValue(ClearSelectionOnCommandProperty, value);
}
public static readonly DependencyProperty ClearSelectionOnCommandProperty =
DependencyProperty.RegisterAttached(
"ClearSelectionOnCommand",
typeof(bool),
typeof(SelectorBehavior),
new UIPropertyMetadata(false, OnClearSelectionOnCommandChanged));
public static void OnClearSelectionOnCommandChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
Selector selector = d as Selector;
if (selector == null) return;
bool nv = (bool)e.NewValue, ov = (bool)e.OldValue;
if (nv == ov) return;
if (nv)
{
selector.CommandBindings.Add(
new CommandBinding(
ClearSelectionCommand,
ClearSelectionCommand_Executed,
ClearSelectionCommand_CanExecute));
}
else
{
var cmd = selector
.CommandBindings
.Cast<CommandBinding>()
.SingleOrDefault(x =>
x.Command == ClearSelectionCommand);
if (cmd != null)
selector.CommandBindings.Remove(cmd);
}
}
public static void ClearSelectionCommand_Executed(
object sender,
ExecutedRoutedEventArgs e)
{
Selector selector = (Selector)sender;
selector.SelectedIndex = -1;
}
public static void ClearSelectionCommand_CanExecute(
object sender,
CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
}
示例用法 - XAML:
Example usage - XAML:
<Window x:Class="ClearSelectionBehaviorLibrary.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ClearSelectionBehaviorLibrary"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Style x:Key="MyStyle" TargetType="Selector">
<Setter
Property="local:SelectorBehavior.ClearSelectionOnCommand"
Value="True"/>
</Style>
</Window.Resources>
<Grid>
<DockPanel>
<Button
DockPanel.Dock="Bottom"
Content="Clear"
Command="{x:Static local:SelectorBehavior.ClearSelectionCommand}"
CommandTarget="{Binding ElementName=TheListBox}"/>
<ListBox
Name="TheListBox"
ItemsSource="{Binding MyData}"
Style="{StaticResource MyStyle}"/>
</DockPanel>
</Grid>
</Window>
示例用法 - 代码隐藏:
Example usage - Code Behind:
public partial class Window1 : Window
{
public List<string> MyData { get; set; }
public Window1()
{
MyData = new List<string>
{
"aa","bb","cc","dd","ee"
};
InitializeComponent();
DataContext = this;
}
}
这篇关于使用控件模板中的按钮清除 wpf 列表框选择并且没有代码隐藏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!