用 ItemsSource IEnumerable 中的默认值替换 NULL

Replace NULL with a default Value in an ItemsSource IEnumerable

我有一个 Custom Control 派生自 ItemsControl.

我的想法来自

在上面的问题中,他们在视图模型中使用了集合

private ObservableCollection<string> _collection = new ObservableCollection<string>();

public ObservableCollection<string> Collection
{
    get { return _collection; }
    set
    {
        _collection = value;
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Collection"));
    }
}

XAML代码是

<Window x:Class="SampleControl.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SampleControl" 
        Title="MainWindow" Height="400" Width="525">
    <Grid>
        <local:BTextBox 
            ItemsSource="{Binding Collection}" 
            ProviderCommand="{Binding AutoBTextCommand}" 
            AutoItemsSource="{Binding SuggCollection}" />
    </Grid>
</Window>

如果我删除了 new ObservableCollection<string>(); 那么它将变成

private ObservableCollection<string> _collection;

public ObservableCollection<string> Collection
{
    get { return _collection; }
    set
    {
        _collection = value;
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Collection"));
    }
}

现在 属性 Collection 保持值 NULL。此 属性 绑定在 ItemsSource 中。那么,我怎样才能将数据推送到 ItemsSource

CustomControl 方法是

private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
    var tb = d as BTextBox;
    if ((e.NewValue != null) && ((tb.ItemsSource as IList) != null)) {
        foreach (var item in e.NewValue as IEnumerable) {
            (tb.ItemsSource as IList).Add(item);
        }
    }
}

在这个方法中,它检查 NULL,如果 ItemsSourceNOT NULL,然后它推送数据。

if ((e.NewValue != null) && ((tb.ItemsSource as IList) != null))。如果 ItemsSourceNOT NULL,那么只有项目被推入集合 (tb.ItemsSource as IList).Add(item);

请帮助我,如何在 Null-able IEnumerable 中分配值?

每当您向 ObservableCollection 添加数据时,只需在此之前添加一个构造函数。这是我的一贯做法。

例如,

Collection = new ObservableCollection<string>();
...add data to the collection here

视情况而定。

编辑

如果您想要自定义控件级别的解决方案,也许可以尝试这样的操作:

var tb = d as BTextBox;
if (((tb.ItemsSource as IList) == null))
    tb.ItemsSource = new IList<string>(); // or new ObservableCollection, List, or any suitable datatype, just to give default values
if ((e.NewValue != null) && ((tb.ItemsSource as IList) != null)) { // probably remove the checking for ((tb.ItemsSource as IList) != null) since we initialized it
...

我们可以添加Item,在添加Item之前我们需要创建一个Instance

if(this.ItemsSource == null)
{
    this.ItemsSource = (new List<object>()).AsEnumerable();
}

(tb.ItemsSource as IList).Add(item);

现在,它不会抛出任何NULL引用异常