你剛剛提醒我,我一直想要這一段時間,所以我寫了一個(帶片斷,這是一個十分鐘的工作)。讓我知道如果這與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。 –