在自定义用户控件中绑定ObservableCollection

本文关键字:绑定 ObservableCollection 控件 自定义 用户 | 更新日期: 2023-09-27 18:02:26

我有一个ObservableCollection,它是在用户控件中创建的,包含一个自定义类。自定义类包含一些字符串和布尔值,没什么特别的。

public class StringLineInfo : INotifyPropertyChanged
{
    private string name { set; get; }
    private Color color { set; get; }
    private bool visible { set; get; }
    private bool follow { set; get; }
    public string Name
    {
        get { return name; }
        set
        {
            name = value;
            NotifyPropertyChanged("Name");
        }
    }
    public Color Color
    {
        get { return color; }
        set
        {
            color = value;
            NotifyPropertyChanged("Color");
        }
    }
    public bool Visible
    {
        get { return visible; }
        set
        {
            visible = value;
            NotifyPropertyChanged("Visible");
        }
    }
    public bool Follow
    {
        get { return follow; }
        set
        {
            follow = value;
            NotifyPropertyChanged("Follow");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this,
                new PropertyChangedEventArgs(propertyName));
        }
    }
}

在自定义控件的Xaml中,我添加了自定义图例控件。在自定义图例中,我有一个ItemsControl绑定到的另一个ObservableCollection。

在legend.xaml:

                                <!--<Image Name="imgMyImage" Grid.Column="1" Height="30" Width="30" Margin="5" Source="{Binding Name, Converter=NameToSrcConverter, ConverterParameter={StaticResource IconDictionary}}" />-->
                            <TextBlock Name="txtlineName" FontSize="12" Foreground="Black"  Text="{Binding Converter={StaticResource nameConverter}}"  Margin="5" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="2"/>
                        </Grid>
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

在legend. example .cs:

    public ObservableCollection<StringLineInfo> allLines = new ObservableCollection<StringLineInfo>();
    public Dictionary<string, string> DvrIconDictionary = new Dictionary<string, string>();
    public Legend()
    {
        InitializeComponent();
        DataContext = this;
        itmCtrol.ItemsSource = allLines;
    }
    // to set the ItemsSource
    public void setItemsSource(ObservableCollection<StringLineInfo> source)
    {
        if (itmCtrl.ItemsSource == null)
        {
            itmCtrl.ItemsSource = source;
        }
    }

在主用户控件的构造函数中,我将图例中的ObservableCollection设置为等于主用户控件中的ObservableCollection。

public MainControl()
    {
        InitializeComponent();
        MapLegend.SizeChanged += new SizeChangedEventHandler(MapLegend_SizeChanged);
        MapLegend.allLines = this.allLines;
    }

即使两个observablecollection总是包含相同的数据(他们现在是相同的对象)ItemsControl将不会更新或显示任何东西。然而,如果我在后面的代码中设置ObservableCollections等于,比如单击按钮,那么它就可以正常工作。

按钮只是调用"setItemsSource"函数。

你知道为什么我不能在启动时设置它们相等吗?

在自定义用户控件中绑定ObservableCollection

您实际上有三个引用到您试图绑定的allLines集合。

  1. 包含MainControl方法的类型中的所有行。
  2. allLines within . legend. example .cs.
  3. itmCtrol。ItemsSource within . legend. example .cs.

我假设第一个引用被正确填充,因为您最终看到的是数据。第二个引用是用一个不需要的空ObservableCollection初始化的(您可以节省初始化这个对象的开销)。第三个被设置为与第二个相同的空集合。

MainControl方法中的代码将第二个引用设置为正确填充的集合,但不以任何方式影响第三个引用(itmCtrl.ItemsSource) -它保留对空集合的引用。

我的猜测是,你正在使用的代码,如以下在legend.xaml.cs中的按钮点击事件'works just fine'。

itmCtrol。

这将交换itmCtrol。ItemsSource从空集合到正确填充的集合的引用。

最简单的解决方案是将allLines字段替换为直接委托给itmCtrol的属性。ItemSource属性(使用itmCtrol。ItemsSource属性作为新属性的后备字段)。它看起来像这样。

    public ObservableCollection<StringLineInfo> AllLines
    {
        get
        {
            return (IObservableCollection<StringLineInfo>)itmCtrol.ItemsSource;
        }
        set
        {
            itmCtrol.ItemsSource = value;
        }
    }