你刚刚提醒我,我一直想要这一段时间,所以我写了一个(带片断,这是一个十分钟的工作)。让我知道如果这与Xamarin合作,我无法用这个测试。
更新:今天我必须半睡半醒。我将“StackLayout”读为“StackPanel”。 OP将其改编为Xamarin,并将该工作代码公布为另一个答案。
using System;
using System.Windows;
using System.Windows.Controls;
namespace HollowEarth.AttachedProperties
{
public static class PanelBehaviors
{
public static void UpdateChildFirstLastProperties(Panel panel)
{
for (int i = 0; i < panel.Children.Count; ++i)
{
var child = panel.Children[i];
SetIsFirstChild(child, i == 0);
SetIsLastChild(child, i == panel.Children.Count - 1);
}
}
#region PanelExtensions.IdentifyFirstAndLastChild Attached Property
public static bool GetIdentifyFirstAndLastChild(Panel panel)
{
return (bool)panel.GetValue(IdentifyFirstAndLastChildProperty);
}
public static void SetIdentifyFirstAndLastChild(Panel panel, bool value)
{
panel.SetValue(IdentifyFirstAndLastChildProperty, value);
}
/// <summary>
/// Behavior which causes the Panel to identify its first and last children with attached properties.
/// </summary>
public static readonly DependencyProperty IdentifyFirstAndLastChildProperty =
DependencyProperty.RegisterAttached("IdentifyFirstAndLastChild", typeof(bool), typeof(PanelBehaviors),
// Default MUST be false, or else True won't be a change in
// the property value, so PropertyChanged callback won't be
// called, and nothing will happen.
new PropertyMetadata(false, IdentifyFirstAndLastChild_PropertyChanged));
private static void IdentifyFirstAndLastChild_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Panel panel = (Panel)d;
((Panel)d).LayoutUpdated += (s, e2) => UpdateChildFirstLastProperties(panel);
}
#endregion PanelExtensions.IdentifyFirstAndLastChild Attached Property
#region PanelExtensions.IsFirstChild Attached Property
public static bool GetIsFirstChild(UIElement obj)
{
return (bool)obj.GetValue(IsFirstChildProperty);
}
public static void SetIsFirstChild(UIElement obj, bool value)
{
obj.SetValue(IsFirstChildProperty, value);
}
/// <summary>
/// True if UIElement is first child of a Panel
/// </summary>
public static readonly DependencyProperty IsFirstChildProperty =
DependencyProperty.RegisterAttached("IsFirstChild", typeof(bool), typeof(PanelBehaviors),
new PropertyMetadata(false));
#endregion PanelExtensions.IsFirstChild Attached Property
#region PanelExtensions.IsLastChild Attached Property
public static bool GetIsLastChild(UIElement obj)
{
return (bool)obj.GetValue(IsLastChildProperty);
}
public static void SetIsLastChild(UIElement obj, bool value)
{
obj.SetValue(IsLastChildProperty, value);
}
/// <summary>
/// True if UIElement is last child of a Panel
/// </summary>
public static readonly DependencyProperty IsLastChildProperty =
DependencyProperty.RegisterAttached("IsLastChild", typeof(bool), typeof(PanelBehaviors),
new PropertyMetadata(false));
#endregion PanelExtensions.IsLastChild Attached Property
}
}
用例:
<StackPanel
xmlns:heap="clr-namespace:HollowEarth.AttachedProperties"
heap:PanelBehaviors.IdentifyFirstAndLastChild="True"
HorizontalAlignment="Left"
Orientation="Vertical"
>
<StackPanel.Resources>
<Style TargetType="Label">
<Setter Property="Content" Value="Blah blah" />
<Setter Property="Background" Value="SlateGray" />
<Setter Property="Margin" Value="4" />
<Style.Triggers>
<Trigger Property="heap:PanelBehaviors.IsFirstChild" Value="True">
<Setter Property="Background" Value="DeepSkyBlue" />
<Setter Property="Content" Value="First Child" />
</Trigger>
<Trigger Property="heap:PanelBehaviors.IsLastChild" Value="True">
<Setter Property="Background" Value="SeaGreen" />
<Setter Property="Content" Value="Last Child" />
</Trigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<Label />
<Label />
<Label />
<Label />
</StackPanel>
这是一个痛点。我曾经写过一个ListBox子类,它在它拥有的项目容器上设置布尔FirstItem/LastItem附加属性。我想你可以写一个与StackPanel的子项相同的行为。一旦你有了,你可以在LastItem属性中轻松地使用触发器编写一个Style。 –