简体   繁体   中英

Items Control and Items Template within another Items Control/Data Template

I am trying to display an Items Control which contains another Items control representing an array of LED indicators. The LED array and all the other data in the main Item Control is bound to an Observable collection. I can't get the LED array to display. I also know I'm having an issue with the IValueConverter to convert byte to brush color (the entire byte array comes in but I want it to just do one element at a time and even when I hard code the return value the LED doesn't display). I just can't figure out what I'm doing wrong (I'm pretty new at all this). Thanks in advance for any advice!

My code behind for ValueConverter

namespace Test
{
    public class ByteToBrushConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return ((byte)value == 1) ? Brushes.LightGreen : Brushes.DarkOliveGreen;
        }
    }

    class userData : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private byte[] led;
        public byte[] Led
        {    
            get { return led; }
            set
            {
                byte[] input = value;
                if (input != this.led)
                {
                    this.led = input;
                    NotifyPropertyChanged();
                }
            }
        }       

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
}

My Xaml code

<Window x:Class="Test.MainWindow"
        xmlns:src="clr-namespace:Test"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        Title="MainWindow" WindowState="Maximized" WindowStyle="None">
    <Window.Resources>

        <src:ByteToBrushConverter x:Key="LEDConverter" />
        <DataTemplate x:Key="myLedTemplate" DataType="{x:Type sys:Byte}">
            <Grid>
                <Border Height="12" Width="12" BorderThickness="1" BorderBrush="Black" Background="{Binding Led,Converter={StaticResource LEDConverter}}" />
            </Grid>
        </DataTemplate>
        <DataTemplate x:Key="myHwTemplate">
            <Grid Margin="10,10,10,10" MinWidth="110" MinHeight="90">
               <Border BorderBrush="Black" BorderThickness="2" >
                    <Grid Margin="0,0,0,0" >
                        <Grid.RowDefinitions>
                            <RowDefinition Height="1*"/>
                            <RowDefinition Height="1*"/>
                            <RowDefinition Height="1*"/>
                        </Grid.RowDefinitions>
                        <Label Grid.Row="0" x:Name="userControlNameLabel" Content="{Binding Path=name}" />
                        <Label Grid.Row="1" x:Name="powerLabel" Background="{Binding Path=Power, Converter={StaticResource int2color}}" HorizontalAlignment="Stretch" Content="Powered" HorizontalContentAlignment="Center" Margin="5,1,5,1" />
                        <Grid Grid.Row="2" Margin="5,5,0,0">
                            <ItemsControl ItemsSource="{Binding Path=Led,Converter={StaticResource LEDConverter}}" ItemTemplate="{StaticResource myLedTemplate}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
                                <ItemsControl.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <WrapPanel IsItemsHost="True" />
                                    </ItemsPanelTemplate>
                                </ItemsControl.ItemsPanel>
                            </ItemsControl>
                        </Grid>
                    </Grid>
                </Border>
            </Grid>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <Grid Margin="0,60,0,0" >
            <ItemsControl Name="ssedu0ItemControl" ItemTemplate="{StaticResource myHwTemplate}" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Disabled" >
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel Orientation="Vertical" IsItemsHost="True"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </Grid>
    </Grid>
</Window>

Here's my main code

namespace Test
{
    public partial class MainWindow : Window
    {
        private ObservableCollection<userData> ssedu0LBData = new ObservableCollection<userData>();

        public MainWindow()
        {
            InitializeComponent();

            for (int i = 0; i < Properties.Settings.Default.unit.Count; i++)
                ssedu0LBData.Add(new userData(Properties.Settings.Default.unit[i]));
            ssedu0ItemControl.ItemsSource = ssedu0LBData;

            for(int i=0;i<8;i++)
                ssedu0LBData[1].Led[i] = 1;
        }   
    }
}

Your main problem is here:

ItemsSource="{Binding Path=Led,Converter={StaticResource LEDConverter}}" 

You don't want to run the collection through a converter, and certainly your converter doesn't currently work on a collection. So that line should be:

ItemsSource="{Binding Path=Led}" 

You would use the converter later on in the data template for that ItemsControl, when you did something like:

<Border BorderBrush="{Binding Path=. Converter={StaticResource LEDConverter}}"/>

A word of warning about your code. Changing individual elements of that array will not propagate to the UI. You need to use a wrapper around your byte that implements INPC, or just replace the whole array instead of changing individual elements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM