以下是如何在不使用 ItemsControl 的情况下创建矩阵的方法,请注意,您属于主要内容 - 为项目指定模板的能力。
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace GridDefs
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//
this.DataContext = this; // alterantively use RelativeSource
}
public IEnumerable<Item> MyItems
{
get
{
List<Item> items = new List<Item>(3);
items.Add(Item.Create("A1", new Point(0, 0)));
items.Add(Item.Create("B2", new Point(1, 1)));
items.Add(Item.Create("C3", new Point(2, 2)));
return items;
}
}
}
public interface IMatrixItem
{
Point Position { get; }
}
// Model, note - it has to implement INotifyPropertyChanged if
// you want to propagate its changes up to the UI
public class Item: IMatrixItem
{
public static Item Create(string text,
Point position)
{
Item item = new Item();
item.Text = text;
item.Position = position;
return item;
}
public string Text
{
get;
private set;
}
public Point Position
{
get;
private set;
}
}
public class GridEx
{
public static DependencyProperty DimensionProperty =
DependencyProperty.RegisterAttached("Dimension",
typeof(Size),
typeof(GridEx),
new PropertyMetadata(new Size(0, 0),
(o, e) =>
{
GridEx.OnDimensionChanged((Grid)o, (Size)e.NewValue);
}));
public static DependencyProperty PositionProperty =
DependencyProperty.RegisterAttached("Position",
typeof(Point),
typeof(GridEx),
new FrameworkPropertyMetadata(new Point(-1, -1),
(o, e) =>
{
GridEx.OnPostionChanged((UIElement)o, (Point)e.NewValue);
}));
public static DependencyProperty ItemStyleProperty =
DependencyProperty.RegisterAttached("ItemStyle",
typeof(Style),
typeof(GridEx));
public static DependencyProperty ItemsProperty =
DependencyProperty.RegisterAttached("Items",
typeof(IEnumerable<IMatrixItem>),
typeof(GridEx),
new PropertyMetadata((o, e) =>
{
GridEx.OnItemsChanged((Grid)o, (IEnumerable<IMatrixItem>)e.NewValue);
}));
#region "Dimension"
private static void OnDimensionChanged(Grid grid, Size resolution)
{
grid.RowDefinitions.Clear();
grid.ColumnDefinitions.Clear();
for (int i = 0; i < resolution.Width; i++)
{
grid.ColumnDefinitions.Add(new ColumnDefinition());
}
for (int i = 0; i < resolution.Height; i++)
{
grid.RowDefinitions.Add(new RowDefinition());
}
}
public static void SetDimension(Grid grid, Size dimension)
{
grid.SetValue(GridEx.DimensionProperty, dimension);
}
public static Size GetDimension(Grid grid)
{
return (Size)grid.GetValue(GridEx.DimensionProperty);
}
#endregion
#region "Position"
private static void OnPostionChanged(UIElement item, Point position)
{
item.SetValue(Grid.ColumnProperty, Convert.ToInt32(position.X));
item.SetValue(Grid.RowProperty, Convert.ToInt32(position.Y));
}
private static T GetParentOfType<T>(DependencyObject current)
where T : DependencyObject
{
for (DependencyObject parent = VisualTreeHelper.GetParent(current);
parent != null;
parent = VisualTreeHelper.GetParent(parent))
{
T result = parent as T;
if (result != null)
return result;
}
return null;
}
public static void SetPosition(UIElement item, Point position)
{
item.SetValue(GridEx.PositionProperty, position);
}
public static Point GetPosition(UIElement grid)
{
return (Point)grid.GetValue(GridEx.PositionProperty);
}
#endregion
#region "ItemStyle"
public static void SetItemStyle(Grid item, Style style)
{
item.SetValue(GridEx.ItemStyleProperty, style);
}
public static Style GetItemStyle(Grid grid)
{
return (Style)grid.GetValue(GridEx.ItemStyleProperty);
}
#endregion
#region "Items"
private static void OnItemsChanged(Grid grid, IEnumerable<IMatrixItem> items)
{
grid.Children.Clear();
// template
Style style = GetItemStyle(grid);
foreach (IMatrixItem item in items)
{
Control itemControl = new Control();
grid.Children.Add(itemControl);
itemControl.Style = style;
itemControl.DataContext = item;
}
}
public static void SetItems(Grid grid, IEnumerable<IMatrixItem> items)
{
grid.SetValue(GridEx.ItemsProperty, items);
}
public static IEnumerable<IMatrixItem> GetItems(Grid grid)
{
return (IEnumerable<IMatrixItem>)grid.GetValue(GridEx.ItemsProperty);
}
#endregion
}
}
标记:
<Window x:Class="GridDefs.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:GridDefs"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="Control" x:Key="t">
<Setter Property="local:GridEx.Position" Value="{Binding Position}"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Button Content="{Binding Text}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid local:GridEx.Dimension="3,3"
local:GridEx.ItemStyle="{StaticResource t}"
local:GridEx.Items="{Binding MyItems}">
</Grid>
</Window>