WPF工具栏-检测项目何时设置为ToolBarOverflowPanel

WPF工具栏-检测项目何时设置为ToolBarOverflowPanel,wpf,Wpf,我知道IsOverflowOpen和HasOverflowItems属性,但我正在寻找一种方法来判断项目(按钮、radiobutton…)是否已移动到工具栏OverflowPanel中,以便使用触发器更改其样式 我需要这个能够复制一些UWP工具栏样式(Windows10Mail,Word,Excel…)。我已经成功地复制了大部分样式,唯一缺少的是能够在溢出面板中更改我的项目的样式 在我试图复制的屏幕截图上,您可以清楚地看到,特殊的标识和行距按钮已经根据它们是显示还是溢出而改变了样式。 您不能只使

我知道IsOverflowOpen和HasOverflowItems属性,但我正在寻找一种方法来判断项目(按钮、radiobutton…)是否已移动到工具栏OverflowPanel中,以便使用触发器更改其样式

我需要这个能够复制一些UWP工具栏样式(Windows10Mail,Word,Excel…)。我已经成功地复制了大部分样式,唯一缺少的是能够在溢出面板中更改我的项目的样式

在我试图复制的屏幕截图上,您可以清楚地看到,特殊的标识和行距按钮已经根据它们是显示还是溢出而改变了样式。

您不能只使用xaml。您必须使用代码隐藏或创建一些附加属性

以下是具有附件属性的解决方案:

首先,您需要创建一个公开2个属性的帮助器类:

  • 将用于触发样式更改的IsInOverflowPanel只读属性
  • TrackParentPanel属性,它是启用/禁用机制
以下是实施方案:

public static class ToolBarHelper
{
    public static readonly DependencyPropertyKey IsInOverflowPanelKey =
        DependencyProperty.RegisterAttachedReadOnly("IsInOverflowPanel", typeof(bool), typeof(ToolBarHelper), new PropertyMetadata(false));

    public static readonly DependencyProperty IsInOverflowPanelProperty = IsInOverflowPanelKey.DependencyProperty;

    [AttachedPropertyBrowsableForType(typeof(UIElement))]
    public static bool GetIsInOverflowPanel(UIElement target)
    {
        return (bool)target.GetValue(IsInOverflowPanelProperty);
    }

    public static readonly DependencyProperty TrackParentPanelProperty =
        DependencyProperty.RegisterAttached("TrackParentPanel", typeof(bool), typeof(ToolBarHelper),
                                             new PropertyMetadata(false, OnTrackParentPanelPropertyChanged));

    public static void SetTrackParentPanel(DependencyObject d, bool value)
    {
        d.SetValue(TrackParentPanelProperty, value);
    }

    public static bool GetTrackParentPanel(DependencyObject d)
    {
        return (bool)d.GetValue(TrackParentPanelProperty);
    }

    private static void OnTrackParentPanelPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var element = d as UIElement;
        if (element != null)
        {
            bool newValue = (bool)e.NewValue;
            if (newValue)
            {
                element.LayoutUpdated += (s, arg) => OnControlLayoutUpdated(element);
            }
        }
    }
    private static void OnControlLayoutUpdated(UIElement element)
    {
        var isInOverflow = TreeHelper.FindParent<ToolBarOverflowPanel>(element) != null;
        element.SetValue(IsInOverflowPanelKey, isInOverflow);
    }
}

public static class TreeHelper
{
    public static T FindParent<T>(this DependencyObject obj) where T : DependencyObject
    {
        return obj.GetAncestors().OfType<T>().FirstOrDefault();
    }

    public static IEnumerable<DependencyObject> GetAncestors(this DependencyObject element)
    {
        do
        {
            yield return element;
            element = VisualTreeHelper.GetParent(element);
        } while (element != null);
    }
}
公共静态类工具栏帮助器
{
公共静态只读DependencyPropertyKey为NoverFlowPanelKey=
DependencyProperty.RegisterAttacheDeliverOnly(“IsInOverflowPanel”、typeof(bool)、typeof(ToolBarHelper)、new PropertyMetadata(false));
公共静态只读DependencyProperty IsInOverflowPanelProperty=IsInOverflowPanelKey.DependencyProperty;
[AttachedPropertyBrowsableForType(类型(UIElement))]
公共静态bool GetIsInOverflowPanel(UIElement目标)
{
return(bool)target.GetValue(IsInOverflowPanelProperty);
}
公共静态只读DependencyProperty TrackParentPanelProperty=
DependencyProperty.RegisterAttached(“TrackParentPanel”)、typeof(bool)、typeof(ToolBarHelper),
新的PropertyMetadata(false,OnTrackParentPanelPropertyChanged));
公共静态无效SetTrackParentPanel(DependencyObject d,布尔值)
{
d、 SetValue(TrackParentPanelProperty,值);
}
公共静态bool GetTrackParentPanel(DependencyObject d)
{
返回(bool)d.GetValue(TrackParentPanelProperty);
}
私有静态无效OnTrackParentPanelPropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
var元素=d作为UIElement;
if(元素!=null)
{
bool newValue=(bool)e.newValue;
如果(新值)
{
element.LayoutUpdated+=(s,arg)=>OnControlLayoutUpdated(element);
}
}
}
私有静态void OnControlLayoutUpdated(UIElement元素)
{
var isInOverflow=TreeHelper.FindParent(元素)!=null;
SetValue(IsInOverflowPanelKey,isInOverflow);
}
}
公共静态类树帮助器
{
公共静态T FindParent(此DependencyObject对象),其中T:DependencyObject
{
返回类型()的obj.getOrderDefault();
}
公共静态IEnumerable GetOrients(此DependencyObject元素)
{
做
{
收益-收益要素;
元素=VisualTreeHelper.GetParent(元素);
}while(元素!=null);
}
}
然后,对于每个需要更改样式的项目,请执行以下操作:

<Button x:Name="DeleteButton" Content="Delete" helpers:ToolBarHelper.TrackParentPanel="True">
    <Button.Style>
        <Style BasedOn="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" TargetType="{x:Type Button}">
            <Style.Triggers>
                <Trigger Property="helpers:ToolBarHelper.IsInOverflowPanel" Value="True">
                    <!-- The Overflow style setters -->
                </Trigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

好主意-非常聪明。