【问题标题】:Items Control and Items Template within another Items Control/Data Template另一个项目控制/数据模板中的项目控制和项目模板
【发布时间】:2015-01-30 17:51:57
【问题描述】:

我正在尝试显示一个 Items 控件,其中包含另一个表示 LED 指示灯数组的 Items 控件。 LED 阵列和主 Item Control 中的所有其他数据都绑定到一个 Observable 集合。我无法让 LED 阵列显示。我也知道我在使用 IValueConverter 将字节转换为画笔颜色时遇到问题(整个字节数组都进来了,但我希望它一次只做一个元素,即使我硬编码 LED 的返回值也不会' t 显示)。我只是不知道我做错了什么(我对这一切都很陌生)。提前感谢您的任何建议!

我的 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));
            }
        }
}

我的 Xaml 代码

<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>

这是我的主要代码

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;
        }   
    }
}

【问题讨论】:

  • 顺便说一句,这个问题做得很好,它有很多代码,但您包含 刚好 来显示所有问题。赞一个!

标签: c# arrays wpf datatemplate itemscontrol


【解决方案1】:

你的主要问题在这里:

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

您不想通过转换器运行集合,当然您的转换器目前不能在集合上工作。所以那行应该是:

ItemsSource="{Binding Path=Led}" 

稍后您将在该 ItemsControl 的数据模板中使用转换器,当您执行以下操作时:

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

关于您的代码的警告。更改该数组的单个元素不会传播到 UI。您需要在实现 INPC 的 byte 周围使用包装器,或者只替换整个数组而不是更改单个元素。

【讨论】:

  • 谢谢,数组现在确实显示了,正如你所指出的,我的更改没有传播到 UI。恐怕我不明白我应该如何解决这个问题。
  • @mkk 好吧,我给了你两个解决方案。你能更详细地解释一下你在哪里感到困惑吗?
  • 在我的实际代码中,我使用了一个函数,该函数从一个字节中提取单个位,组合并重新排列它们并将它们填充到我返回并分配给示例中的 LED 阵列的字节数组中代码。这不是一次替换整个字节数组吗?但画笔颜色仍未显示。实际上,现在没有颜色显示,只是每个 LED 元素周围的边框。
  • @mkk 将“背景”上的绑定更改为“路径=”。而不是“路径=领导”。那应该可以解决您的画笔问题。是的,听起来你替换了所有东西。它只是您的 MainWindow 构造函数没有,所以我担心这种代码也在其他地方。
  • @mkk 没问题。很高兴你明白了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-28
  • 1970-01-01
  • 2016-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多