Also, nachdem ich es gehackt habe, habe ich einen Weg gefunden. Es ist ziemlich eklig, aber es funktioniert.
Wenn ich in WPF bin, würde ich den AlternationIndex verwenden und einen Style-Trigger für den Index 0, 1, 2 setzen und die Randstärke von Index 2 auf einen unteren Index setzen.
In Silverlight haben wir keine AlternationIndex- oder Stil-Trigger. Also musste ich hacken. Ich wickelte den Code in ein Verhalten, so dass meine XAML ist ziemlich sauber:
Controls:DataGrid DataGridLines:HorizontalGridLineModulus.Index="3" ... />
Der Code zu unterstützen, sieht es so aus:
public static class HorizontalGridLineModulus
{
private static readonly DependencyProperty HorizontalGridLineModulusBehaviorProperty =
DependencyProperty.RegisterAttached(
"HorizontalGridLineModulusBehavior",
typeof (HorizontalGridLineModulusBehavior),
typeof (DataGrid),
null);
public static readonly DependencyProperty IndexProperty =
DependencyProperty.RegisterAttached(
"Index",
typeof (int),
typeof (HorizontalGridLineModulus),
new PropertyMetadata(1, IndexChanged)
);
public static int GetIndex(DependencyObject dependencyObject)
{
return (int)dependencyObject.GetValue(IndexProperty);
}
public static void SetIndex(DependencyObject dependencyObject, int value)
{
dependencyObject.SetValue(IndexProperty, value);
}
private static void IndexChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var behavior = dependencyObject.GetValue(HorizontalGridLineModulusBehaviorProperty) as HorizontalGridLineModulusBehavior;
if (behavior == null)
{
behavior = new HorizontalGridLineModulusBehavior(dependencyObject as DataGrid, (int)e.NewValue);
dependencyObject.SetValue(HorizontalGridLineModulusBehaviorProperty, behavior);
}
}
}
public class HorizontalGridLineModulusBehavior
{
private readonly DataGrid _grid;
private readonly int _modulus;
public HorizontalGridLineModulusBehavior(DataGrid grid, int modulus)
{
if(grid == null)
throw new ArgumentException("grid");
_grid = grid;
_modulus = modulus;
_grid.LayoutUpdated += GridLayoutUpdated;
}
private void GridLayoutUpdated(object sender, EventArgs e)
{
DrawBorders();
}
private void DrawBorders()
{
var presenter = _grid.Descendants<DataGridRowsPresenter>().FirstOrDefault();
if(presenter == null) return;
var orderedRows = presenter.Children.OrderBy(child => RowIndex(child));
int count = 0;
foreach (var row in orderedRows)
{
count++;
var gridLine = row.Descendants<Rectangle>().Where(x => x.Name == "BottomGridLine").FirstOrDefault();
if(gridLine != null)
gridLine.Visibility = count % _modulus != 0 ? Visibility.Collapsed : Visibility.Visible;
}
}
private static int RowIndex(UIElement element)
{
var row = element as DataGridRow;
return row == null ? 0 : row.GetIndex();
}
}
Dieser Code Verwendung von wenigen Erweiterungsmethoden macht, definiert hier :
public static class DependencyObjectExtensions
{
public static IEnumerable<DependencyObject> Children(this DependencyObject element)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
yield return VisualTreeHelper.GetChild(element, i);
}
public static IEnumerable<T> Children<T>(this DependencyObject element) where T : DependencyObject
{
return element.Children().Filter<T>();
}
public static IEnumerable<DependencyObject> Descendants(this DependencyObject element)
{
foreach (var child in element.Children())
{
yield return child;
foreach (var descendent in child.Descendants())
yield return descendent;
}
}
public static IEnumerable<T> Descendants<T>(this DependencyObject element) where T : DependencyObject
{
return element.Descendants().Filter<T>();
}
public static IEnumerable<T> Filter<T>(this IEnumerable list) where T : class
{
foreach (var item in list)
{
if (item is T)
yield return (T)item;
}
}
}