WPF 网格自定义布局选择控件 表格布局控件
这个控件是根据Word中插入表格的控件而来的,如图
我根据该控件制作了WPF版的控件。
XAML代码:
<UserControl x:Class="你的项目名称.GridLayout"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SciChartRealTime"
mc:Ignorable="d"
Background="Transparent"
d:DesignHeight="374.919" d:DesignWidth="371.521">
<UserControl.Resources>
<Style TargetType="Rectangle" x:Key="normalRectangle">
<Setter Property="Stroke" Value="#B1000000"/>
<Setter Property="StrokeThickness" Value="1"/>
<Setter Property="Fill" Value="Transparent"/>
<Setter Property="Margin" Value="1"/>
</Style>
<Style TargetType="Rectangle" x:Key="fillRectangle">
<Setter Property="Stroke" Value="#FFEF7919"/>
<Setter Property="StrokeThickness" Value="1"/>
<Setter Property="Fill" Value="Transparent"/>
<Setter Property="Margin" Value="1"/>
</Style>
</UserControl.Resources>
<Grid UseLayoutRounding="True">
<UniformGrid Name="Uniform" Rows="{Binding Rows,RelativeSource={RelativeSource Self}}"
Columns="{Binding Columns,RelativeSource={RelativeSource Self}}">
</UniformGrid>
</Grid>
</UserControl>
C#:
/// <summary>
/// GridLayout.xaml 的交互逻辑
/// </summary>
public partial class GridLayout : UserControl
{
public GridLayout()
{
InitializeComponent();
fillStyle = FindResource("fillRectangle") as Style;
normalStyle = FindResource("normalRectangle") as Style;
Refresh();
MouseLeave += GridLayout_MouseLeave; ;
}
public int Rows
{
get { return (int)GetValue(RowsProperty); }
set { SetValue(RowsProperty, value); }
}
public static readonly DependencyProperty RowsProperty =
DependencyProperty.Register("Rows", typeof(int), typeof(GridLayout), new PropertyMetadata(8, ChangedGrid));
public int Columns
{
get { return (int)GetValue(ColumnsProperty); }
set { SetValue(ColumnsProperty, value); }
}
public static readonly DependencyProperty ColumnsProperty =
DependencyProperty.Register("Columns", typeof(int), typeof(GridLayout), new PropertyMetadata(8, ChangedGrid));
public Vector Value
{
get { return (Vector)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(Vector), typeof(GridLayout), new PropertyMetadata(new Vector(0,0)));
private static void ChangedGrid(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as GridLayout).Refresh();
public event EventHandler GridClicked
{
add { AddHandler(GridClickedEvent, value); }
remove { RemoveHandler(GridClickedEvent, value); }
}
public static readonly RoutedEvent GridClickedEvent = EventManager.RegisterRoutedEvent(
"GridClicked", RoutingStrategy.Bubble, typeof(EventHandler), typeof(GridLayout));
private void Refresh()
{
Uniform.Children.Clear();
for (int r = 0; r < Rows; r++)
{
for (int c = 0; c < Columns; c++)
{
var rect = new Rectangle();
rect.Tag = new Vector(r, c);
rect.Style = normalStyle;
rect.ToolTip = $"{r},{c}";
rect.MouseEnter += Rect_MouseEnter;
rect.MouseLeave += Rect_MouseLeave;
rect.MouseLeftButtonDown += Rect_MouseLeftButtonDown;
Uniform.Children.Add(rect);
}
}
}
private void Rect_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Vector vec = (Vector)(sender as Rectangle).Tag;
GridLayoutArgs routedEvent = new GridLayoutArgs(GridClickedEvent, vec);
RaiseEvent(routedEvent);
}
Style fillStyle;
Style normalStyle;
private void Rect_MouseLeave(object sender, MouseEventArgs e)
{
Vector vec = (Vector)(sender as Rectangle).Tag;
}
private void Rect_MouseEnter(object sender, MouseEventArgs e)
{
Vector vec = (Vector)(sender as Rectangle).Tag;
Value = vec;
foreach (Rectangle item in Uniform.Children)
{
Vector vecNow = (Vector)item.Tag;
if (vecNow.X <= vec.X && vecNow.Y <= vec.Y)
{
item.Style = fillStyle;
}
else
{
item.Style = normalStyle;
}
}
}
private void GridLayout_MouseLeave(object sender, MouseEventArgs e)
{
foreach (Rectangle item in Uniform.Children)
{
item.Style = normalStyle;
}
}
}
public class GridLayoutArgs : RoutedEventArgs
{
public GridLayoutArgs(RoutedEvent routedEvent, Vector vec)
{
RoutedEvent = routedEvent;
Value = vec;
}
public Vector Value { get; set; }
}
使用示例:
<StackPanel Margin="16">
<TextBlock Text="{Binding ElementName=GridL,Path=Value}" HorizontalAlignment="Center" Margin="0 20 0 0"/>
<local:GridLayout x:Name="GridL" Margin="8" Width="200" Height="200" Rows="8" Columns="8" GridClicked="事件处理"</local:GridLayout> </StackPanel>