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

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

问题描述:

我有一个在包含自定义类的用户控件中创建的ObservableCollection。自定义类包含几个字符串和布尔值,没有什么特别的。在自定义用户控件中绑定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.xaml.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; 
    } 

尽管两个ObservableCollections总是包含相同的数据(他们现在是相同的对象)的ItemsControl不会更新或显示任何东西。但是,如果我在代码中稍后设置了ObservableCollections,请点击按钮,那么它工作得很好。

该按钮只是调用“setItemsSource”函数。

关于为什么我不能在启动时将它们设置为平等的任何想法?

+0

如果发布你的问题的代码片段,你会得到更好的答案。 –

+0

@jwJung添加了代码。 – Shawn

+1

它看起来好像来自legend.xaml的一些相关代码缺失。你也可以发布按钮点击'那很好'的代码吗? –

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

  1. allLines中包含MainControl方法的类型。
  2. all legend in legend.xaml.cs。
  3. itmCtrol.ItemsSource withing legend.xaml.cs。

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

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

我的猜测是,您在按钮点击事件中使用了legend.xaml.cs中的以下代码,它可以“正常工作”。

itmCtrol。ItemsSource = allLines;

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

最简单的解决办法是与代表们直奔itmCtrol.ItemSource财产(使用itmCtrol.ItemsSource财产为后盾领域的新属性)的属性替换allLines领域。它看起来像这样。

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

工作得很好的Button在MainControl中,并调用此函数: public void setItemsSource(ObservableCollection source); 它通过原始allLines – Shawn

+0

变量名称是否正确? itmCtrol和itmCtrlDVRs是一样的吗?如果是这样,我上面提供的解决方案是有效的。 –

+0

只需添加解决方案的一些代码。 –