C# 如何在代码中设置固定的列/行定义并在DesignView中使用它们
我想要有固定数量的列和行的网格。例如,80列和24行。 在设计视图中,用户不能更改列和行定义,但必须能够将控件插入单元格 设计视图应该如下所示 我尝试将Grid子类化,并在构造函数中设置列和行定义,但随后单元格根本没有显示在DesignView中C# 如何在代码中设置固定的列/行定义并在DesignView中使用它们,c#,wpf,grid,C#,Wpf,Grid,我想要有固定数量的列和行的网格。例如,80列和24行。 在设计视图中,用户不能更改列和行定义,但必须能够将控件插入单元格 设计视图应该如下所示 我尝试将Grid子类化,并在构造函数中设置列和行定义,但随后单元格根本没有显示在DesignView中 可以这样做吗?如果要查看单元格或正方形,可以将ShowGridLines属性设置为true您可以将网格子类化,以添加依赖属性行和列,并在PropertyChanged回调中更新行定义和列定义 要在设计时获取网格线,如果处于设计模式(DesignerPr
可以这样做吗?如果要查看单元格或正方形,可以将
ShowGridLines
属性设置为true您可以将网格
子类化,以添加依赖属性行
和列
,并在PropertyChanged回调中更新行定义
和列定义
要在设计时获取网格线,如果处于设计模式(DesignerProperties.GetIsInDesignMode(此)==true),则可以在加载的事件中向每个单元格添加边框
像这样使用它
<local:FixedSizeGrid Rows="24"
Columns="80"
Background="#E8E8E8">
<Button Grid.Row="1" Grid.Column="1"/>
<Button Grid.Row="1" Grid.Column="2"/>
<Button Grid.Row="1" Grid.Column="3"/>
</local:FixedSizeGrid>
您是否尝试过Grid.Initialized event handlder并尝试在其中添加您的RowDefinitions和ColumnDefinitions?这看起来很有希望。一旦我添加了一个子元素,我就无法在设计器中看到网格,也无法在“设计”视图中更改网格子元素的宽度/高度/柱/柱跨度/等等,但我将在下周再试一次。但网格确实存在。Thanks@Markus:我在使用ColumnSpan
等时没有问题。虽然行和列的大小为“*”,但我将使用一个选项来更新代码以设置它。我明白你所说的网格消失的意思了,如果你添加和删除了几次子元素,RowDefinitions
和ColumnDefinitions
会因为某种原因被删除。我会调查的。@Markus:更新了我的答案,问题现在应该解决了。试试看,现在网格显示的很好。在“设计”视图中移动或调整子对象的大小是否适合您?如果我试一下,孩子们的宽度和高度都会降到零。@Markus:是的,我找不到任何一种情况会让我崩溃。你能给我一个具体的场景吗?您使用的是什么版本的Visual Studio以及什么操作系统?我已经在Windows7(带SP1的VS2010)和WindowsXP(VS2010)上试过了。
[ContentProperty("ContentChildren")]
public class FixedSizeGrid : Grid
{
#region Dependency Properties
public static readonly DependencyProperty RowsProperty =
DependencyProperty.Register("Rows",
typeof(int),
typeof(FixedSizeGrid),
new FrameworkPropertyMetadata(24, RowsPropertyChanged));
public static readonly DependencyProperty ColumnsProperty =
DependencyProperty.Register("Columns",
typeof(int),
typeof(FixedSizeGrid),
new FrameworkPropertyMetadata(80, ColumnsPropertyChanged));
public static readonly DependencyProperty ContentChildrenProperty =
DependencyProperty.Register("ContentChildren",
typeof(ObservableCollection<UIElement>),
typeof(FixedSizeGrid),
new FrameworkPropertyMetadata(new ObservableCollection<UIElement>()));
#endregion // Dependency Properties
#region Properties
private static void RowsPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
{
FixedSizeGrid fixedSizeGrid = sender as FixedSizeGrid;
fixedSizeGrid.UpdateRowDefinitions();
}
private static void ColumnsPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
{
FixedSizeGrid fixedSizeGrid = sender as FixedSizeGrid;
fixedSizeGrid.UpdateColumnDefinitions();
}
public ObservableCollection<UIElement> ContentChildren
{
get { return (ObservableCollection<UIElement>)GetValue(ContentChildrenProperty); }
set { SetValue(ContentChildrenProperty, value); }
}
public int Rows
{
get { return (int)GetValue(RowsProperty); }
set { SetValue(RowsProperty, value); }
}
public int Columns
{
get { return (int)GetValue(ColumnsProperty); }
set { SetValue(ColumnsProperty, value); }
}
#endregion // Properties
#region Fields
private List<Border> m_designTimeBorders;
#endregion //Fields
#region Constructor
public FixedSizeGrid()
{
if (DesignerProperties.GetIsInDesignMode(this) == true)
{
m_designTimeBorders = new List<Border>();
}
SnapsToDevicePixels = true;
Loaded += FixedSizeGrid_Loaded;
ContentChildren.CollectionChanged += ContentChildren_CollectionChanged;
}
#endregion // Constructor
#region Event Handlers
private void FixedSizeGrid_Loaded(object sender, RoutedEventArgs e)
{
UpdateRowDefinitions();
UpdateColumnDefinitions();
}
private void ContentChildren_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (UIElement element in e.NewItems)
{
RemoveFromParent(element);
Children.Add(element);
}
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
foreach (UIElement element in e.OldItems)
{
Children.Remove(element);
}
}
else if (e.Action == NotifyCollectionChangedAction.Reset)
{
Children.Clear();
}
if (DesignerProperties.GetIsInDesignMode(this) == true)
{
AddDesignTimeBorders();
}
}
#endregion // Event Handlers
#region Private Methods
private void RemoveFromParent(UIElement element)
{
DependencyObject parent = element;
while (parent != null && !(parent is FixedSizeGrid))
{
parent = LogicalTreeHelper.GetParent(parent);
}
if (parent != null)
{
(parent as FixedSizeGrid).Children.Remove(element);
}
}
private void UpdateRowDefinitions()
{
while (RowDefinitions.Count > Rows && RowDefinitions.Count > 0)
RowDefinitions.Remove(RowDefinitions[RowDefinitions.Count-1]);
while (RowDefinitions.Count < Rows)
RowDefinitions.Add(new RowDefinition());
if (DesignerProperties.GetIsInDesignMode(this) == true)
{
AddDesignTimeBorders();
}
}
private void UpdateColumnDefinitions()
{
while (ColumnDefinitions.Count > Columns && ColumnDefinitions.Count > 0)
ColumnDefinitions.Remove(ColumnDefinitions[ColumnDefinitions.Count - 1]);
while (ColumnDefinitions.Count < Columns)
ColumnDefinitions.Add(new ColumnDefinition());
if (DesignerProperties.GetIsInDesignMode(this) == true)
{
AddDesignTimeBorders();
}
}
private void AddDesignTimeBorders()
{
RemoveDesignTimeBorders();
for (int row = 0; row < Rows; row++)
{
for (int column = 0; column < Columns; column++)
{
Border designTimeBorder = new Border();
designTimeBorder.Tag = "DesignTimeBorder";
designTimeBorder.BorderBrush = new SolidColorBrush(Color.FromRgb(154, 191, 229));
designTimeBorder.BorderThickness = new Thickness(0,0,1,1);
Grid.SetRow(designTimeBorder, row);
Grid.SetColumn(designTimeBorder, column);
m_designTimeBorders.Add(designTimeBorder);
}
}
foreach (Border designTimeBorder in m_designTimeBorders)
{
Children.Add(designTimeBorder);
}
}
private void RemoveDesignTimeBorders()
{
foreach (Border designTimeBorder in m_designTimeBorders)
{
Children.Remove(designTimeBorder);
}
m_designTimeBorders.Clear();
}
#endregion // Private Methods
}