使用控件模板中的按钮清除 wpf 列表框选择并且没有代码隐藏 [英] Clear wpf listbox selection using button in control template and no codebehind

查看:28
本文介绍了使用控件模板中的按钮清除 wpf 列表框选择并且没有代码隐藏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为 WPF ListBox 创建一个 Style,它在 ControlTemplate 中包含一个 Button用户可以单击它并清除 ListBox 选择.我不想使用codebehind 以便此Style 可以应用于任何ListBox.我曾尝试使用 EventTriggers 和 Storyboards,但事实证明这是有问题的,因为它只在第一次工作并且停止 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 EventTriggers and Storyboards 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屋!

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