Bạn sẽ có thể thực hiện việc này mà không phải tạo điều khiển tùy chỉnh hoặc người dùng bằng cách sử dụng các thuộc tính được đính kèm.
Đây là một lớp học mà tôi nghĩ rằng sẽ có thể làm những gì bạn muốn. Thay vì ràng buộc các giá trị của Grid.Row
và Grid.RowSpan
vào hàng và chiều cao của bạn, hãy liên kết GridEx.RowFromBottom
và GridEx.RowSpanFromBottom
với chúng. Trình xử lý thay đổi thuộc tính cho các thuộc tính này sẽ tính toán giá trị mới của Grid.Row
dựa trên các giá trị của các thuộc tính đó và số lượng hàng trong lưới.
Một vấn đề tiềm năng là điều này có thể không cập nhật chính xác nếu bạn đang thêm hoặc trừ các hàng từ lưới khi chạy.
public static class GridEx
{
public static readonly DependencyProperty RowFromBottomProperty = DependencyProperty.RegisterAttached("RowFromBottom", typeof(int?), typeof(GridEx), new FrameworkPropertyMetadata(default(int?), FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsParentArrange | FrameworkPropertyMetadataOptions.AffectsParentMeasure, OnRowFromBottomChanged));
public static readonly DependencyProperty RowSpanFromBottomProperty = DependencyProperty.RegisterAttached("RowSpanFromBottom", typeof(int?), typeof(GridEx), new FrameworkPropertyMetadata(default(int?), FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsParentArrange | FrameworkPropertyMetadataOptions.AffectsParentMeasure, OnRowSpanFromBottomChanged));
private static void OnRowFromBottomChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var grid = GetContainingGrid(d);
int? rowFromBottom = (int?) e.NewValue;
int? rowSpanFromBottom = GetRowSpanFromBottom(d);
if (rowFromBottom == null || rowSpanFromBottom == null) return;
int rows = grid.RowDefinitions.Count;
int row = Math.Max(0, Math.Min(rows, rows - rowFromBottom.Value - rowSpanFromBottom.Value));
Grid.SetRow((UIElement) d, row);
}
private static void OnRowSpanFromBottomChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var grid = GetContainingGrid(d);
int? rowFromBottom = GetRowFromBottom(d);
int? rowSpanFromBottom = (int?)e.NewValue;
if (rowFromBottom == null || rowSpanFromBottom == null) return;
int rows = grid.RowDefinitions.Count;
int row = Math.Max(0, Math.Min(rows, rows - rowFromBottom.Value - rowSpanFromBottom.Value));
Grid.SetRow((UIElement)d, row);
Grid.SetRowSpan((UIElement)d, rowSpanFromBottom.Value);
}
public static int? GetRowFromBottom(DependencyObject obj)
{
return (int?) obj.GetValue(RowFromBottomProperty);
}
public static void SetRowFromBottom(DependencyObject obj, int? value)
{
obj.SetValue(RowFromBottomProperty, value);
}
public static int? GetRowSpanFromBottom(DependencyObject obj)
{
return (int?)obj.GetValue(RowSpanFromBottomProperty);
}
public static void SetRowSpanFromBottom(DependencyObject obj, int? value)
{
obj.SetValue(RowSpanFromBottomProperty, value);
}
private static Grid GetContainingGrid(DependencyObject element)
{
Grid grid = null;
while (grid == null && element != null)
{
element = LogicalTreeHelper.GetParent(element);
grid = element as Grid;
}
return grid;
}
}
Nếu bạn có bất kỳ câu hỏi nào về những gì đang diễn ra ở đây, vui lòng hỏi.
Nguồn
2012-04-26 03:58:20
Bạn có thể đưa ra ví dụ minh họa tại sao bạn cần điều đó không? – sll
Tôi đã thêm một ví dụ – Robert
biểu đồ nguội :) – Aftnix