如何容纳ItemsSource和Items

时间:2017-08-31 07:20:16

标签: wpf data-binding

ListBox之类的控件具有ItemsSource属性,您可以将其绑定到

<ListBox x:Name="ListBoxColours" ItemsSource="{Binding Colours}" />

它还有一个Items属性,可用于在后面的代码中添加项目

ListBoxColours.Items.Add("Red");

我正在创建一个ListBox in的CustomControl。我已在我的控件中公开了ItemSource,以允许用户将项目绑定到ViewModel中的属性

<ListBox
     x:Name="PART_ListBox"
     ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource AncestorType=local:TextBoxComboControl}}"
     SelectionMode="Single" />

...

public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(
    "ItemsSource", typeof(IEnumerable), typeof(TextBoxComboControl), new PropertyMetadata(default(IEnumerable)));

public IEnumerable ItemsSource
{
    get { return (IEnumerable) GetValue(ItemsSourceProperty); }
    set { SetValue(ItemsSourceProperty, value); }
}

...

<local:TextBoxComboControl ItemsSource="{Binding Colours}" />

我想添加用户在后面的代码中添加项目的能力,但是,他们不想使用绑定。我想知道ItemSource / Items属性如何与彼此互动。为了允许他们使用peoprty,我必须将ListBox项绑定到我控制范围内的两个属性。

1 个答案:

答案 0 :(得分:1)

ListBox源自Selector,源自ItemsControl

如果查看ItemsControl的源代码:

你可以看到:

/// <summary> 
///     ItemsSource specifies a collection used to generate the content of
/// this control.  This provides a simple way to use exactly one collection 
/// as the source of content for this control. 
/// </summary>
/// <remarks> 
///     Any existing contents of the Items collection is replaced when this
/// property is set. The Items collection will be made ReadOnly and FixedSize.
///     When ItemsSource is in use, setting this property to null will remove
/// the collection and restore use to Items (which will be an empty ItemCollection). 
///     When ItemsSource is not in use, the value of this property is null, and
/// setting it to null has no effect. 
/// </remarks>
    [Bindable(true), CustomCategory("Content")]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
    public IEnumerable ItemsSource
    {
        get { return Items.ItemsSource; }
        set
        {
            if (value == null) 
            { 
                ClearValue(ItemsSourceProperty);
            } 
            else
            {
                SetValue(ItemsSourceProperty, value);
            } 
        }
    } 

如果查看类型为Items的{​​{1}}属性...它可以是两种模式之一(ItemsSource模式或“直接”模式)。

ItemsCollection

有一个名为/// <summary> /// ItemCollection will contain items shaped as strings, objects, xml nodes, /// elements, as well as other collections. (It will not promote elements from /// contained collections; to "flatten" contained collections, assign a /// <seealso cref="System.Windows.Data.CompositeCollection"/> to /// the ItemsSource property on the ItemsControl.) /// A <seealso cref="System.Windows.Controls.ItemsControl"/> uses the data /// in the ItemCollection to generate its content according to its ItemTemplate. /// </summary> /// <remarks> /// When first created, ItemCollection is in an uninitialized state, neither /// ItemsSource-mode nor direct-mode. It will hold settings like SortDescriptions and Filter /// until the mode is determined, then assign the settings to the active view. /// When uninitialized, calls to the list-modifying members will put the /// ItemCollection in direct mode, and setting the ItemsSource will put the /// ItemCollection in ItemsSource mode. /// </remarks> 的内部成员被设置/清除以跟踪它所处的模式 - 这会使各种方法/属性的行为有所不同,具体取决于模式。

“项目”是通过_isUsingItemsSource(保存在CollectionView成员中)访问的 - 这可以指向包含对直接项目的访问权限的_collectionView,或者{由于设置了“itemssource”而在调用InnerItemCollectionView时使用CollectionView创建的{1}}。

您最有可能从CollectionViewSource.GetDefaultCollectionView派生,因此您需要提供类似的行为。也许你可以从SetItemsSource派生出来以获得这种行为......如果合适的话,取决于你当然的控制权。