【问题标题】:How do you get ListBoxItem.IsMouseCaptured to trigger style changes?如何让 ListBoxItem.IsMouseCaptured 触发样式更改?
【发布时间】:2021-12-13 21:43:09
【问题描述】:

我正在使用以下样式:

<Style x:Key="ListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
    <Setter Property="Foreground" Value="{DynamicResource Button-Foreground}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <TextBlock Padding="10"
                            Background="{TemplateBinding Background}"
                            Foreground="{TemplateBinding Foreground}">
                    <ContentPresenter/>
                </TextBlock>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Foreground" Value="{DynamicResource Button-Foreground-Disabled}"/>
        </Trigger>
        <Trigger Property="IsMouseCaptured" Value="True">
            <Setter Property="Background" Value="{DynamicResource Button-Background-Hover}"/>
            <Setter Property="Foreground" Value="{DynamicResource Button-Foreground}"/>
        </Trigger>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsMouseOver" Value="True"/>
                <Condition Property="IsMouseCaptured" Value="False"/>
            </MultiTrigger.Conditions>
            <Setter Property="Background" Value="{DynamicResource Button-Background-Hover}"/>
            <Setter Property="Foreground" Value="{DynamicResource Button-Foreground-Hover}"/>
        </MultiTrigger>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsSelected" Value="True"/>
                <Condition Property="IsMouseOver" Value="False"/>
            </MultiTrigger.Conditions>
            <Setter Property="Background" Value="{DynamicResource Button-Foreground}"/>
            <Setter Property="Foreground" Value="{DynamicResource Button-Foreground-Hover}"/>
        </MultiTrigger>
    </Style.Triggers>
</Style>

我遇到的问题是IsMouseCaptured 触发器永远不会发生。即使我点击它,它仍然保持IsMouseOver 样式(背景是故意相同的颜色,但我尝试更改只是为了进行实验,它根本没有改变,前景当然也没有改变)。

有没有办法在单击特定列表框项时触发它?所有其他触发器都按预期工作。

【问题讨论】:

  • 只是为了分享我所注意到的,似乎IsMouseCaptured 属性在ListBoxItem 的情况下永远不会改变,而IsMouseCaptureWithin 属性在它承载IsMouseCaptured 属性变化的UIElement 时会发生变化,例如Button.

标签: wpf xaml triggers


【解决方案1】:

有没有办法在单击特定列表框项时触发它?

不使用任何内置属性。

您可以创建自己的自定义 ListBoxItem,添加一个您可以绑定到的 IsPressed 属性:

public class CustomListBoxItem  : ListBoxItem
{
    public static readonly DependencyProperty IsPressedProperty = DependencyProperty.Register(
        nameof(IsPressed), typeof(bool), typeof(CustomListBoxItem), new PropertyMetadata(false));

    public bool IsPressed
    {
        get => (bool)GetValue(IsPressedProperty);
        set => SetValue(IsPressedProperty, value);

    }
    protected override void OnMouseDown(MouseButtonEventArgs e)
    {
        base.OnMouseDown(e);
        IsPressed = true;
    }

    protected override void OnMouseUp(MouseButtonEventArgs e)
    {
        base.OnMouseUp(e);
        IsPressed = false;
    }
}

除非您明确创建 ListBoxItem 元素,否则您还需要一个自定义 ListBox 来生成您的自定义类型的容器:

public class CustomListBox : ListBox
{
    protected override DependencyObject GetContainerForItemOverride() =>
        new CustomListBoxItem();
}

【讨论】:

  • 这是解决方案,我不得不覆盖更多的事件处理程序来补偿点击和拖动,它在单选模式下工作,这是我需要的,未经多次测试。我添加了一个 OnMouseEnter,如果按下 MouseDevice.LeftButton,则将 IsPressed 设置为 true,并添加一个 OnMouseLeave,将 IsPressed 设置为 false。
猜你喜欢
  • 1970-01-01
  • 2011-01-30
  • 2019-01-12
  • 2018-10-17
  • 2021-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多