UserControl中依赖项属性列表框的ItemsSource

时间:2019-07-31 11:01:52

标签: c# .net wpf data-binding dependency-properties

我在C#WPF MVVM中开发了新的桌面应用程序,但是数据绑定存在问题。 我创建了自己的UserControl

<UserControl x:Class="Project.View.UserControls.BusListDeviceControl"
             x:Name="BusList"
             ...
             >
    <Grid Grid.Column="0" Grid.Row="0" Margin="7, 5">
        <Grid.RowDefinitions>
            <RowDefinition Height="60"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="50"/>
        </Grid.RowDefinitions>
        <ListBox Grid.Row="1" ItemsSource="{Binding ElementName=BusList, Path=ItemsSource}" Background="{Binding ElementName=BusList, Path=BackgroundColor}" BorderBrush="{x:Null}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid Margin="0,2">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="25" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <Image Grid.Column="0" Margin="5" Source="{Binding IconPath}"/>
                        <TextBlock Grid.Column="1" Text="{Binding Name}" FontFamily="Century Gothic" VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="16"/>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</UserControl>

隐藏代码

public partial class BusListDeviceControl : UserControl, INotifyPropertyChanged
    {
        ObservableCollection<Device> devices;
        string color;

        public static readonly DependencyProperty DevicesProperty =
            DependencyProperty.Register("Devices", typeof(ObservableCollection<Device>), 
            typeof(BusListDeviceControl), new PropertyMetadata (new ObservableCollection<Device>()));
        public ObservableCollection<Device> Devices
        {
            get { return this.devices; }
            set
            {
                this.devices = value;
                RaisePropertyChanged("Devices");
            }
        }

        public static readonly DependencyProperty BackgroundColorProperty =
        DependencyProperty.Register("BackgroundColor", typeof(string), typeof(BusListDeviceControl));
        public string BackgroundColor
        {
            get { return color; }
            set
            {
                this.color = value;
                RaisePropertyChanged("BackgroundColor");
            }
        }

        public BusListDeviceControl()
        {
            InitializeComponent();
        }

        internal void RaisePropertyChanged(string prop)
        {
            if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }

我想在mainView中使用此UserControl。

<UserControl x:Class="Project.View.UserControls.IdentificationControl"
             ...>
    <UserControl.DataContext>
        <vm:IdentificationControlViewModel/>
    </UserControl.DataContext>
    <Grid Grid.Column="0" Margin="0">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="70" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <local:BusListDeviceControl Devices="{Binding Buses[0].Devices}" BackgroundColor="White" Grid.Column="0" Grid.Row="0" Margin="7, 5"></local:BusListDeviceControl>
        </Grid>
    </Grid>
</UserControl>

在IdentificationControlViewModel.cs中,我有 公共ObservableCollection巴士{组; },每辆公交车都有公共的ObservableCollection设备{组; }。 当我将所有UserControl xaml代码放到mainView上时,绑定工作正常,但是当我只想使用干净的代码时,ItemsSource的绑定不起作用,而BackgroundColor绑定正常。

如何在我的UserControl中将Bus [0] .Devices正确绑定到ItemsSource?

1 个答案:

答案 0 :(得分:1)

问题是您没有正确使用DependencyProperty。 有关更多信息,请参见here

基本上,当您使用DependencyProperty时,您使用类中的字段,并且属性应如下所示:

public string BackgroundColor
{
    get { return (string)GetValue(BackgroundColorProperty); }
    set
    {
       SetValue(BackgroundColorProperty,value);
    }
 }

GetValueSetValue继承自DependencyObject

此外,当您使用DependencyProperty时,无需实现INotifyPropertyChanged

您的班级应该像这样:

public partial class BusListDeviceControl : UserControl
    {

        public static readonly DependencyProperty DevicesProperty =
            DependencyProperty.Register("Devices", typeof(ObservableCollection<Device>), 
            typeof(BusListDeviceControl), new PropertyMetadata (new ObservableCollection<Device>()));
        public ObservableCollection<Device> Devices
        {
            get { return (ObservableCollection<Device>)GetValue(DevicesProperty ); }
            set
            {
                SetValue(DevicesProperty ,value);
            }
        }

        public static readonly DependencyProperty BackgroundColorProperty =
        DependencyProperty.Register("BackgroundColor", typeof(string), typeof(BusListDeviceControl));
        public string BackgroundColor
        {
            get { return (string)GetValue(BackgroundColorProperty);  }
            set
            {
                SetValue(BackgroundColorProperty,value);
            }
        }

        public BusListDeviceControl()
        {
            InitializeComponent();
        }
    }