Search code examples
c#wpfmvvmcontrols

WPF - MVVM - How to realize a structure similar to the attached image


My application monitors data related to different hardware channels. Each channel is reading a list of items, named labels. Each label is made of a numeric ID, a boolean indicating its validity, and an array of three bytes.

My Model is currently made as follows:

public class ArincLabel
{
    public byte Label { get; set; }
    public byte[] Content { get; set; }
}

public class ArincLabelRx
{
    public bool IsValid { get; set; }
    public ArincLabel ArincLabel { get; set; }
}

public Dictionary<string, List<ArincLabelRx>> Arinc429RxData;

Each time a new batch of labels is read, an event is raised and consumed by the ViewModel.

I need to show to end user the content of all the labels. In LabVIEW, I would be able to draw such a structure:

LabVIEW array of cluster

I have no idea of how to realize a similar structure in WPF. Can you please give me some suggestions?

Please consider that I'm in total control of the application, I can modify every aspect of it, I'm trying to understand what is the best way to implement my requirement.

PS Boolean indicator is already available as WPF item from National Instruments, no need to draw it from scratch.

EDIT: ItemsControl with ItemTemplate, along with sample layout, solved my problem. Thank you very much.


Solution

  • You need to refine it but it should give you a place to start: you should turn the entire thing into a custom control and the columns into another custom control as it says in the comments.

    The green circles are checkboxes with a style that shows their state (Checked or Unchecked) with a dark or limegreen circle

    Result:

    enter image description here

             <Border BorderBrush="Gray" Background="LightGray" BorderThickness="2" MaxWidth="142" HorizontalAlignment="Left">
                <StackPanel HorizontalAlignment="Left">                    
                    <Grid Margin="2">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="auto"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock>Channel</TextBlock>
                        <TextBox Grid.Column="1" Margin="5,0,0,0">AMMC_TX1</TextBox>
                    </Grid>
                        <ScrollViewer VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Visible">
                    <UniformGrid HorizontalAlignment="Left" Rows="1">
                            <!--Turn me into a custom control-->
                            <Border BorderBrush="Gray" BorderThickness="2" MaxWidth="50">
                                <StackPanel>
                                    <TextBlock>Label</TextBlock>
                                    <TextBox>1</TextBox>
                                    <CheckBox IsChecked="True" Margin="5">
                                        <CheckBox.Style>
                                            <Style TargetType="CheckBox">
                                                <Setter Property="Template">
                                                    <Setter.Value>
                                                        <ControlTemplate TargetType="CheckBox">
                                                            <Grid>
                                                                <Ellipse Name="eli" Height="30" Width="30" Fill="DarkGreen"/>
                                                            </Grid>
                                                            <ControlTemplate.Triggers>
    
                                                                <Trigger Property="IsChecked" Value="True">
                                                                    <Setter TargetName="eli" Property="Fill" Value="Lime"/>
                                                                </Trigger>
                                                            </ControlTemplate.Triggers>
                                                        </ControlTemplate>
                                                    </Setter.Value>
                                                </Setter>
    
                                            </Style>
                                        </CheckBox.Style>
                                    </CheckBox>
                                    <TextBlock>Content</TextBlock>
                                    <TextBox>11</TextBox>
                                    <TextBox>22</TextBox>
                                    <TextBox>33</TextBox>
                                </StackPanel>
                            </Border>
                            <!--Turn me into a custom control-->
                            <Border BorderBrush="Gray" BorderThickness="2" MaxWidth="50">
                                <StackPanel>
                                    <TextBlock>Label</TextBlock>
                                    <TextBox>1</TextBox>
                                    <CheckBox IsChecked="True" Margin="5">
                                        <CheckBox.Style>
                                            <Style TargetType="CheckBox">
                                                <Setter Property="Template">
                                                    <Setter.Value>
                                                        <ControlTemplate TargetType="CheckBox">
                                                            <Grid>
                                                                <Ellipse Name="eli" Height="30" Width="30" Fill="DarkGreen"/>
                                                            </Grid>
                                                            <ControlTemplate.Triggers>
    
                                                                <Trigger Property="IsChecked" Value="True">
                                                                    <Setter TargetName="eli" Property="Fill" Value="Lime"/>
                                                                </Trigger>
                                                            </ControlTemplate.Triggers>
                                                        </ControlTemplate>
                                                    </Setter.Value>
                                                </Setter>
    
                                            </Style>
                                        </CheckBox.Style>
                                    </CheckBox>
                                    <TextBlock>Content</TextBlock>
                                    <TextBox>11</TextBox>
                                    <TextBox>22</TextBox>
                                    <TextBox>33</TextBox>
                                </StackPanel>
                            </Border>
                            <!--Turn me into a custom control-->
                            <Border BorderBrush="Gray" BorderThickness="2" MaxWidth="50">
                                <StackPanel>
                                    <TextBlock>Label</TextBlock>
                                    <TextBox>1</TextBox>
                                    <CheckBox IsChecked="True" Margin="5">
                                        <CheckBox.Style>
                                            <Style TargetType="CheckBox">
                                                <Setter Property="Template">
                                                    <Setter.Value>
                                                        <ControlTemplate TargetType="CheckBox">
                                                            <Grid>
                                                                <Ellipse Name="eli" Height="30" Width="30" Fill="DarkGreen"/>
                                                            </Grid>
                                                            <ControlTemplate.Triggers>
    
                                                                <Trigger Property="IsChecked" Value="True">
                                                                    <Setter TargetName="eli" Property="Fill" Value="Lime"/>
                                                                </Trigger>
                                                            </ControlTemplate.Triggers>
                                                        </ControlTemplate>
                                                    </Setter.Value>
                                                </Setter>
    
                                            </Style>
                                        </CheckBox.Style>
                                    </CheckBox>
                                    <TextBlock>Content</TextBlock>
                                    <TextBox>11</TextBox>
                                    <TextBox>22</TextBox>
                                    <TextBox>33</TextBox>
                                </StackPanel>
                            </Border>
                        </UniformGrid>
                        </ScrollViewer>
                </StackPanel>
                </Border>