我有一个在用户控件中创建的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中,我添加了自定义图例控件。在自定义图例中,我有另一个ObservableCollection,ItemsControl可以数据绑定到。
在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 :(得分:2)
您实际上有三个对要尝试绑定的allLines集合的引用。
我假设第一个引用正在正确填充,因为您最终会看到数据。第二个引用使用不需要的空ObservableCollection初始化(您可以节省初始化此对象的开销)。第三个设置为与第二个相同的空集合。
您在MainControl方法中的代码设置对正确填充的集合的第二个引用,但不会以任何方式影响第三个引用(itmCtrl.ItemsSource) - 它保留对空集合的引用。
我的猜测是你在legend.xaml.cs中使用了以下代码,这些代码在'工作得很好'的按钮点击事件中。
itmCtrol.ItemsSource = allLines;
这会将空集合中的itmCtrol.ItemsSource引用交换为正确填充的引用。
最简单的解决方案是将allLines字段替换为直接委托给itmCtrol.ItemSource属性的属性(使用itmCtrol.ItemsSource属性作为新属性的支持字段)。它看起来像这样。
public ObservableCollection<StringLineInfo> AllLines { get { return (IObservableCollection<StringLineInfo>)itmCtrol.ItemsSource; } set { itmCtrol.ItemsSource = value; } }