【发布时间】:2019-12-02 13:00:39
【问题描述】:
我正在使用 WPF 构建桌面应用程序,我需要能够以一种看起来井井有条的方式动态添加视图。
我创建了一个ObservableCollection,并将itemsControl.ItemsSource 设置为该集合。
我可以添加视图,只是看起来很糟糕。
关于可以添加的视图数量,我所知道的是最多可以有 16 个视图。
我考虑过创建一个动态网格,它会根据可用视图的数量而变化,如下图所示
所以我尝试采用动态网格的想法, 每次要添加/删除视图(听起来很糟糕)时,我都会创建一个新网格,并且根据视图集合的大小,我知道如何正确拆分网格。
然后我遍历集合中的所有现有视图,并通过正确的逻辑将它们放置在网格上。我在这里弄得一团糟,所以如果我完全走错了方向,请告诉我。
代码如下:
public partial class DynamicTargetView : UserControl
{
private ObservableCollection<TargetView> views = new ObservableCollection<TargetView>();
public Grid grid;
public DynamicTargetView()
{
InitializeComponent();
SettingsBar.onViewChange += addOrRemoveTargetsFromPanel;
}
public void addOrRemoveTargetsFromPanel(Object sender, WeiTargetGui.EventArgs.AddOrRemoveViewEventArgs e)
{
if (e.isShown)
{
addTargetToPanel(e.id);
}
else removeTargetFromPanel(e.id);
}
public void addTargetToPanel(string id)
{
views.Add(new TargetView(Int32.Parse(id)));
ArrangeGrid();
}
public void removeTargetFromPanel(string id)
{
foreach (TargetView v in views)
{
if (v.id == Int32.Parse(id))
views.Remove(v);
}
ArrangeGrid();
}
public void ArrangeGrid()
{
int NumOfViews = views.Count();
grid = new Grid();
grid.Children.Clear();
ColumnDefinition gridCol1;
ColumnDefinition gridCol2;
ColumnDefinition gridCol3;
ColumnDefinition gridCol4;
RowDefinition gridRow1;
RowDefinition gridRow2;
RowDefinition gridRow3;
RowDefinition gridRow4;
if (NumOfViews == 1)
{
addtoGrid(0, 0);
}
else if (NumOfViews == 2)
{
gridCol1 = new ColumnDefinition();
gridCol2 = new ColumnDefinition();
grid.ColumnDefinitions.Add(gridCol1);
grid.ColumnDefinitions.Add(gridCol2);
addtoGrid(2, 0);
}
else if (NumOfViews < 5)
{
gridCol1 = new ColumnDefinition();
gridCol2 = new ColumnDefinition();
gridRow1 = new RowDefinition();
gridRow2 = new RowDefinition();
grid.ColumnDefinitions.Add(gridCol1);
grid.ColumnDefinitions.Add(gridCol2);
grid.RowDefinitions.Add(gridRow1);
grid.RowDefinitions.Add(gridRow2);
addtoGrid(2, 2);
}
else if (NumOfViews < 10)
{
gridCol1 = new ColumnDefinition();
gridCol2 = new ColumnDefinition();
gridCol3 = new ColumnDefinition();
gridRow1 = new RowDefinition();
gridRow2 = new RowDefinition();
gridRow3 = new RowDefinition();
grid.ColumnDefinitions.Add(gridCol1);
grid.ColumnDefinitions.Add(gridCol2);
grid.ColumnDefinitions.Add(gridCol3);
grid.RowDefinitions.Add(gridRow1);
grid.RowDefinitions.Add(gridRow2);
grid.RowDefinitions.Add(gridRow3);
addtoGrid(3, 3);
}
else if (NumOfViews < 17)
{
gridCol1 = new ColumnDefinition();
gridCol2 = new ColumnDefinition();
gridCol3 = new ColumnDefinition();
gridCol4 = new ColumnDefinition();
gridRow1 = new RowDefinition();
gridRow2 = new RowDefinition();
gridRow3 = new RowDefinition();
gridRow4 = new RowDefinition();
grid.ColumnDefinitions.Add(gridCol1);
grid.ColumnDefinitions.Add(gridCol2);
grid.ColumnDefinitions.Add(gridCol3);
grid.ColumnDefinitions.Add(gridCol4);
grid.RowDefinitions.Add(gridRow1);
grid.RowDefinitions.Add(gridRow2);
grid.RowDefinitions.Add(gridRow3);
grid.RowDefinitions.Add(gridRow4);
addtoGrid(4, 4);
}
}
public void addtoGrid(int cols, int rows)
{
int row = 0;
int column = 0;
foreach (var view in views)
{
if (cols == 0 && rows == 0)
{
grid.Children.Add(view);
break;
}
if (cols == 2 && rows == 0)
{
Grid.SetColumn(view, column);
column++;
grid.Children.Add(view);
}
else
{
if (column != cols)
{
Grid.SetColumn(view, column);
Grid.SetRow(view, row);
grid.Children.Add(view);
}
if (column < cols)
column++;
else
{
column = 0;
row++;
}
}
}
this.Content = grid;
}
}
TargetView 是一个用户控件,它代表一个带有一些关于该目标的数据的目标。
所以这里是代码的问题-
1) 在视图集合中添加多个组件时,出现以下异常:
System.InvalidOperationException: '指定元素已经是另一个元素的逻辑子元素。先断开它。'
我已经添加了grid.Children.Clear() - 没有任何帮助。
2) 最后一个问题 - 代码看起来很糟糕,我只想让它工作,这样我下次可以更好地学习和实现它。
我们将不胜感激,非常感谢。
【问题讨论】:
标签: c# wpf dynamic-view