如何将Observable动态数据集合绑定到UserControls数组

时间:2015-01-23 19:28:25

标签: c# wpf data-binding user-controls observablecollection

我已经在C#和WPF上教了几个月了,而且我已经被困在这个最新的问题上几天了。我每秒收到一个关于众多单位的数据流(数字和标志字节)。我想使用UserControl显示此数据并使用数据绑定进行更新。由于该项目需要在窗口中显示42个这样的单元,因此我将UserControls放在一个数组中。但是,我无法使数据绑定工作。我尽可能多地删除了代码,但我知道这仍然很多。问题在于绑定。我无法弄清楚正确的语法。

这是My UserControl

<UserControl x:Name="TestUserControl"
             x:Class="Test.UserControl1">

            <Label x:Name="userControlNameLabel" Content="UNIT x" />
            <Label x:Name="powerLabel" Content="    Powered"/>
            <Label Content="V in"/>
            <Label x:Name="vinData" Content="{Binding Path=VinDisplay, ElementName=UserControl1}" >
        </Grid>
</UserControl>

这是我的UserControl代码:

namespace Test
{
    public partial class UserControl1 : UserControl, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public UserControl1()
        {
            InitializeComponent();
        }

        private byte vin;
        public byte Vin
        {
            get { return (byte)GetValue(VinProperty); }
            set 
            {   SetValue(VinProperty, (byte)value);
                NotifyPropertyChanged("Vin");
            }
        }

        private int power;
        public int Power
        {
            get { return power; }
            set
            {
                power = value;
                if (power == 1)
                {
                    powerLabel.Background = LEDONCOLOR;
                    powerLabel.Foreground = BLACKFONT;
                }
                else
                {
                    powerLabel.Background = LEDOFFCOLOR;
                    powerLabel.Foreground = WHITEFONT;
                }
            }
        }

        public string UserControlName
        {
            get { return userControlNameLabel.Content.ToString(); }
            set { userControlNameLabel.Content = value; }
        }

        public static DependencyProperty VinProperty   = DependencyProperty.Register("Vin",   typeof(byte), typeof(UserControl));
        public static DependencyProperty PowerProperty = DependencyProperty.Register("Power", typeof(int),  typeof(UserControl));

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

    }
}

这是Observable Collection

namespace Test
{
    class userData : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public String name { get; private set; }
        private byte voltageIn;
        public byte VoltageIn
        {
            get
            {
                return voltageIn;
            }

            set
            {
                if (value != this.voltageIn)
                {
                    this.voltageIn = value;
                    NotifyPropertyChanged();
                }
            }
        }

        private int power;
        public int Power
        {
            get
            {
                return power;
            }

            set
            {
                if (value != this.power)
                {
                    this.power = value;
                    NotifyPropertyChanged();
                }
            }
        }

        public userData(string name, byte voltageIn, int power)
        {
            this.name = name;
            this.voltageIn = voltageIn;
            this.power = power;
        }
        public userData(string name)
        {
            this.name = name;
            this.voltageIn = 0x00;
            this.power = 0;
        }

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

    }

}

这是我的主窗口

<Window x:Class="Test.MainWindow"            
        xmlns:src="clr-namespace:Test"
        xmlns:local="clr-namespace:Test"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        Title="MainWindow" >
    <Grid>
        <Grid>
            <Label Content="HW 0"/>
            <src:UserControl1 x:Name="hw0unit1"  Vin="{Binding Path=_userData[0].VoltageIn, Mode=OneWay}" />
            <src:UserControl1 x:Name="hw0unit2"/>
        </Grid>
        <Grid>
            <Label Content="HW 1"/>
            <src:UserControl1 x:Name="hw1unit1"/>
            <src:UserControl1 x:Name="hw1unit2"/>
        </Grid>
    </Grid>
</Window>

我的主程序

namespace Test
{
    public partial class MainWindow : Window
    {
        DispatcherTimer hwScan;

        UserControl1[] userCntrl = new UserControl1[4];

        byte[] vinDisplay = new byte[4];
        int[] powerDisplay = new int[4];

        ObservableCollection<userData> _userData;

        // Main Routine
        public MainWindow()
        {
            InitializeComponent();

            // Create dispatch timer to call hwTimer_Tick
            ...

            // Save off UserControls for all units into Array for easier access
            userCntrl[0] = hw0unit1;
            userCntrl[1] = hw0unit2;
            userCntrl[2] = hw1unit1;
            userCntrl[3] = hw1unit2;

            // Init userData arrays
            _userData = new ObservableCollection<userData>();
            for (int i = 0; i < Properties.Settings.Default.unit.Count; i++)
                _userData.Add(new userData(Properties.Settings.Default.unit[i]));
        }

        private void hwTimer_Tick(object sender, EventArgs e)
        {
            // Hardcode data for testing
            vinDisplay[i] = a hex constant
            powerDisplay[i] = a hex constant

            for (int i=0; i<4; i++)
            {
                _userData[i].VoltageIn = vinDisplay[i];
                _userData[i].Power     = powerDisplay[i];
            }
        }

    }
}

0 个答案:

没有答案