使用控件模板按钮,并没有codebehind清除WPF列表框选择 [英] Clear wpf listbox selection using button in control template and no codebehind

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

问题描述

我想创建一个风格的WPF 的ListBox ,其中包括一个按钮控件模板,用户可以点击它清除的ListBox 选择。
我不想使用codebehind使这一风格可以应用到任何的ListBox
我已经尝试使用的EventTrigger 故事板和它已被证明有问题的,因为它仅适用于第一次和停止故事板设置previous选择回来。
我知道我可以使用一个用户的控制,但我想知道是否可以用这个来实现仅风格

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>

用法示例 - code背后:

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;
    }
}

这篇关于使用控件模板按钮,并没有codebehind清除WPF列表框选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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