0

我目前正在使用 C# WPF 4.5 并试图创建一个交互式网格。给定网格单元格的正方形大小(宽度 = 高度)、列数和行数,我想在屏幕上动态生成网格。

对于生成的网格,我希望网格线可见。我认为这可以通过在每个单元格内绘制一个边框来模拟,如果没有别的。最重要的是,我需要一个事件来确定用户单击的单元格(即单击返回网格列和行时),并且能够一次选择一个或多个单元格。

关于如何创建这样的东西的任何帮助或想法,或者有更好的方法吗?提前致谢!

编辑:所以这是我取得的一些进展:

  1. 创建了一个自定义复选框:

        <Style x:Key="styleCustomCheckBox" TargetType="{x:Type CheckBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type CheckBox}">
                    <Grid x:Name="Background" Background="Transparent">
                        <Rectangle x:Name="fillCheckBox"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsChecked" Value="False">
                            <Setter TargetName="fillCheckBox" Property="Fill" Value="Transparent"/>
                        </Trigger>
                        <Trigger Property="IsChecked" Value="True">
                            <Setter TargetName="fillCheckBox" Property="Fill" Value="Red"/>
                            <Setter TargetName="fillCheckBox" Property="Opacity" Value=".3"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

然后只需使用该样式的自定义复选框填充网格:

<CheckBox Grid.Column="1" Grid.Row="1" Style="{StaticResource styleCustomCheckBox}" />

所以现在我想在网格中映射每个复选框,我可以在其中收集复选框是否被选中以及它在哪个网格行和列中,我该怎么做?

4

1 回答 1

2

我会使用ItemsControl并将其ItemsPanelTemplate设置为 a UniformGrid,并将其ItemTemplate设置为您的CheckBox

如果您可以将您绑定ItemsControl.ItemsSource到后面代码中的数据对象集合,那将是最简单的。例如:

<ItemsControl ItemsSource="{Binding MyCollection}">
    <!-- ItemsPanelTemplate -->
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Rows="5" Columns="5" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <!-- ItemTemplate -->
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border BorderBrush="Red" BorderThickness="1">
               <CheckBox Style="{StaticResource styleCustomCheckBox}" />
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

如果您需要指定选中项的行或列索引,您可以将其添加到您的数据项并使用常规Grid而不是 a UniformGrid,并应用ItemContainerStyle这样的:

<!-- ItemContainerStyle -->
<ItemsControl.ItemContainerStyle>
    <Style>
        <Setter Property="Grid.Column" Value="{Binding ColumnIndex}" />
        <Setter Property="Grid.Row" Value="{Binding RowIndex}" />
    </Style>
</ItemsControl.ItemContainerStyle>

要确定点击的项目,这取决于您如何构建数据对象以及您在点击中实际想要执行的操作。

如果您想要正方形后面的数据项,您可以使用DataContext,例如

void MyCheckBox_Clicked(object sender, EventArgs e)
{
    var selectedItem = ((CheckBox)sender).DataContext;
}

或者,如果您有类似具有以下IsChecked属性的数据项:

<CheckBox IsChecked="{Binding IsChecked}" 
          Style="{StaticResource styleCustomCheckBox}" />

您可以轻松地将事件附加到PropertyChanged数据项IsChecked属性的事件,并在那里运行一些代码。

作为第三种选择,您可以使用 aButton并将ItemTemplate所选项目作为CommandParameter

<Border BorderBrush="Red" BorderThickness="1">
    <Button CommandParameter="{Binding }" ... />
</Border>

我不能给你一个明确的答案,因为我不知道你的代码库和你想要做什么,但我希望这能给你足够的信息给你一个粗略的开始,并为你指明正确的方向情况。

于 2013-02-28T17:49:33.133 回答