我开始使用IReactiveList<ICoordVm>
,其中:
interface ICoordViewModel
{
object X {get;}
object Y {get;}
ViewModel ViewModel {get;}
}
我想从此列表创建一个网格,其中每个ViewModel的视图位于相应的X / Y坐标。此外,必须根据X和Y的ToString()
值标记行和列。最后,我希望避免重新绘制整个网格,因为新项目会添加到我的列表中。
我正在考虑是否使用网格,数据网格或其他东西。使用第二个解决方案here中描述的数据表/数据网格似乎得到了行和标题列,但似乎我需要注入一个新的数据表并在每次添加项目时重绘屏幕。使用this解决方案中描述的GridHelper可能会给我一种避免重绘的方法,但是没有描述如何包含行和列标题。
任何人都有任何创意,如何解决这个问题?
答案 0 :(得分:0)
这是我最终提出的解决方案。 This链接帮助很大;我直接盗取了XAML:
<DataTemplate x:Key="DataTemplateLevel2">
<ContentPresenter Content="{Binding}"/>
</DataTemplate>
<DataTemplate x:Key="DataTemplateLevel1">
<ItemsControl ItemsSource="{Binding}" ItemTemplate="{DynamicResource DataTemplateLevel2}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:DisplayGridViewModel}">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Lists}" ItemTemplate="{DynamicResource DataTemplateLevel1}"/>
</ScrollViewer>
</DataTemplate>
以下是我的viewmodel的精简版。基本技巧是当网格尺寸已知时调用Initialize方法;此方法使用以下内容填充网格:
接下来,当新的视图模型到达时,调用Add方法来查找应放置视图模型的X / Y位置,并将其注入占位符;当发生这种情况时,它会在网格中显示在适当的位置。 (所有视图模型都是XAML中的模板)。
public class DisplayGridViewModel
{
// Fields and constructor.
public void Initialize()
{
var rows = GetRows().ToList();
var columns = GetColumns().ToList();
_lists.Clear();
var cornerHeader = new CornerHeaderDisplayViewModel(_displayEditor /* + other content */);
var columnHeaders = columns.Select(c => new ColumnHeaderViewModel(c, _displayEditor));
_lists.Add(new ReactiveList<object>(Enumerable.Repeat((object)cornerHeader, 1).Union(columnHeaders)));
var index = 1;
foreach (var row in rows)
{
_lists.Add(new ReactiveList<object>());
_lists[index].Add(new RowHeaderViewModel(row, _displayEditor /* + other content */));
foreach (var column in columns)
{
_lists[index].Add(new CellViewModel(_displayEditor /* + other content */));
}
index++;
}
}
private IEnumerable<object> GetRows()
{
// custom implementation
}
private IEnumerable<object> GetColumns()
{
// custom implementation
}
public void Add(ICoordChart coordChart)
{
var match = _lists.SelectMany(l => l).OfType<CoordViewModel>().Single(cc => IsMatch(cc, coordChart));
match.ViewModel = coordChart.ViewModel;
}
private static bool IsMatch(ICoordChart cc, ICoordChart chart)
{
// custom implementation
}
private readonly IReactiveList<IReactiveList<object>> _lists = new ReactiveList<IReactiveList<object>>();
public IReactiveList<IReactiveList<object>> Lists
{
get { return _lists; }
}
}
最后有一个DisplayEditorViewModel,它提供了单元格宽度和高度的中心位置。这允许用户调整UI上其他位置的显示尺寸,并自动调整单元格的大小。
对任何不清楚的事情表示歉意。希望这里的代码能够为解决这个问题的其他人提供一些高级线索,同时避免过多不必要的细节。