3

在接下来的几天里,我将开始一个相当大的项目,我考虑了创建项目的最佳方式。现在我有一个关于控件的重要问题,我真的不知道实现它的最佳方法是什么。

我有一个 LED 灯矩阵。(32x16 LED)。这些必须显示在网格中,现在是棘手的部分。我必须能够和他们一起做很多事情。例如,我必须能够很容易地访问数据绑定的 LED 进行一些操作,例如将它们全部向右或向左移动 2 次或反转它们等等。

我想过在这样的 itemcontrol 中显示它们:

<ItemsControl ItemsSource="{Binding Path=Leds}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Rows="16" Columns="32"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type local:Led}">
                <Ellipse Name="ellipse" Fill="Green"/>
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding Path=State}" Value="Off">
                        <Setter TargetName="ellipse" Property="Fill" Value="Red"/>
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

但是我应该如何处理led上的鼠标点击来转动它或关闭它。(我正在使用 MVVM)您将如何抽象 LED 中的整个网格?

有很多解决方案,但我不知道该采取哪一个?

愿你有一个有趣的想法,如何创建一个简单而干净的解决方案。

4

2 回答 2

2

代替 a UniformGrid,考虑Grid在你的ItemsControl和绑定的Grid.Column和你的对象上的一个值Grid.Row使用正则。ItemContainerStyle这将使执行诸如移动整个列或行之类的事情变得更加容易。

你可以写出 16 和 32 行/列的定义,或者我在我的博客上有一些附加的属性,可以让你用一行来做到这一点。

<ItemsControl ItemsSource="{Binding Leds}">
    <!-- ItemsPanelTemplate -->
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid local:GridHelpers.RowCount="16"
                  local:GridHelpers.ColumnCount="32" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

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

    <!-- ItemTemplate -->
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            ...
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

至于单击它们以打开/关闭它们,请将每个项目包装在Button标签中并覆盖Template以看起来您想要的方式。然后您可以将Command事件绑定到 ViewModel 中的属性,并将选定的 LED 作为CommandParameter

<Button Command="{Binding RelativeSource={RelativeSource ItemsControl}, Path=DataContext.ToggleLedCommand}"
        CommandParameter="{Binding }">
    <Button.Template>
        <ControlTemplate TargetType="{x:Type Button}">
            <Ellipse Name="ellipse" Fill="Green"/>
            <ControlTemplate.Triggers>
                <DataTrigger Binding="{Binding Path=State}" Value="Off">
                    <Setter TargetName="ellipse" Property="Fill" Value="Red"/>
                </DataTrigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
   </Button.Template>
</Button>

而您的 Command 实现将只是

void ToggleLed(LedModel led)
{
    led.State = (led.State == "On" ? "Off" : "On");
}
于 2012-08-09T13:37:07.053 回答
0

UniformGrid我宁愿建议您使用此 stackoverflow 线程中DataGrid2D引入的出色控件,而不是使用 .

它允许您将DataGrid2D's绑定ItemsSource到 2D 对象,在您的情况下为 a Led[,],然后将显示您在 2D 数组中的任何更改。假设您想切换两个 LED,例如从位置 [1,2] 到 [2,5],您只需要在Led[,]阵列上执行此操作,视图就会相应地自行更新

于 2012-08-09T13:33:45.947 回答