在向每个网格“单元格”添加内容时,如何提高性能?

时间:2012-03-28 20:55:59

标签: wpf

我有一个ItemsControl绑定到一组极其基本的ViewModel,每个ViewModel都有一个row \ col-Postion属性。我也在使用Caliburn.Micro MVVM Framework,它会自动使用匹配的View(这只是一个简单的矩形,Fill =“Transparent”)我在开始时用这些填充网格,所以我可以添加ContextMenus给他们,并知道单击了哪个单元格等。

ItemsPanelTemplate是一个Grid,ItemContainerStyle将Grid.Row \ Column绑定到Position.X \ Y属性。

此屏幕是一个屏幕编辑器,用于模拟旧的80x25文本模式系统,该系统最初使用自定义光栅字体绘制一些简单的图形。原始系统可以处理其中8个屏幕。我正在使用矩形和矢量绘图来提高灵活性,并将屏幕尺寸扩展到任何尺寸。

第一个想法,就是简单地为(i){for(j){Add}}循环遍历网格,并为每个单元格添加一个新的BlankVM。

它有效,但因为它必须做2000次,所以它很慢。绑定等很快,但它增加了很多。由于潜在的屏幕尺寸可以根据需要大小,因此 要窒息。现在大约40多秒。

我不是那么优秀的程序员(还是!)所以我不知所措。

我可以用更高效的东西替换for循环吗?

由于除了位置(行,列)之外,BlankCells都是相同的,我可以利用它吗?

也许我甚至不需要将所有这些添加到网格中,如果有更简单的方法可以使用上下文菜单并知道我点击的单元格...

这是代码:

public class BlankCellViewModel : PropertyChangedBase, IEditorCell
{
    public GridPosition Position { get; set; }

    public BlankCellViewModel(GridPosition position) {
        Position = position;
    }
}

和视图

<UserControl x:Class="EditorCells.BlankCellView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
      <Rectangle>
        <Rectangle.ContextMenu>
          <ContextMenu>
            <MenuItem Header="New Track Segment Here" />
          </ContextMenu>
        </Rectangle.ContextMenu>
        <Rectangle.Style>
          <Style>
            <Setter Property="Rectangle.Fill"
                    Value="Transparent" />
            <Style.Triggers>
              <Trigger Property="Rectangle.IsMouseOver"
                       Value="True">
                <Setter Property="Rectangle.Fill"
                        Value="White" />
              </Trigger>
            </Style.Triggers>
          </Style>
        </Rectangle.Style>
      </Rectangle>
</UserControl>

从包含的Viewmodel,问题循环

private void SetupEditorGrid()
    {
        EditorMap.Resize(MaxRow, MaxColumn);
        for (int i = 0; i < MaxRow; i++)
        {
            for (int j = 0; j < MaxColumn; j++)
            {
                AddCell(new BlankCellViewModel(new GridPosition(j, i)));
            }
        }
    }

及其观点:

<UserControl x:Class="EditorView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:ap="clr-namespace:Support.AttachedProperties;assembly=Systems"
         HorizontalAlignment="Center">
  <ItemsControl x:Name="EditorCells">
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
        <Grid ShowGridLines="True"
              Background="Black"
              HorizontalAlignment="Center"
              VerticalAlignment="Center"
              ap:GridHelpers.RowCount="{Binding RowCount}"
              ap:GridHelpers.ColumnCount="{Binding ColumnCount}" >
          <Grid.Resources>
            <Style TargetType="{x:Type ColumnDefinition}">
              <Setter Property="Width"
                      Value="8" />
            </Style>
            <Style TargetType="{x:Type RowDefinition}">
              <Setter Property="Height"
                      Value="16" />
            </Style>
          </Grid.Resources>
        </Grid>
      </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
      <Style>
        <Setter Property="Grid.Row"
                Value="{Binding Position.Row}" />
        <Setter Property="Grid.Column"
                Value="{Binding Position.Column}" />
         </Style>
    </ItemsControl.ItemContainerStyle>
  </ItemsControl>
</UserControl>

1 个答案:

答案 0 :(得分:0)

与其他人交谈。

由于网格单元格是已知的,固定大小的,使用过的MouseMove事件处理程序来计算鼠标结束的单元格,并使用网格本身的上下文菜单。