【问题标题】:Interactive Grid WPF交互式网格 WPF
【发布时间】:2013-02-26 01:50:28
【问题描述】:

我目前正在使用 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}" />

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

【问题讨论】:

  • 蓝色边框是默认ListBox 样式的一部分。你可以很容易地改变它。

标签: c# wpf grid interactive


【解决方案1】:

我会使用 ItemsControl 并将其 ItemsPanelTemplate 设置为 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 而不是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}" />

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-13
    • 1970-01-01
    • 2015-09-02
    • 2020-02-22
    • 2023-04-07
    • 2019-01-26
    • 1970-01-01
    相关资源
    最近更新 更多