【问题标题】:WPF Custom Control - How do you bind a listbox from a static ObservableCollection?WPF 自定义控件 - 如何从静态 ObservableCollection 绑定列表框?
【发布时间】:2010-06-28 17:45:36
【问题描述】:

我不确定该怎么做。我在 NameField.cs 类中有一个静态 ObservableCollection。我只是不知道如何将它绑定到列表框。

  • 我不应该使用 ListBox 吗?
  • 我应该使用 DependencyProperty 吗?
  • 我应该通过属性还是公开公开 ObservableCollection?

我不知道在这里做什么......

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace MyWPF
{

    [TemplatePart(Name = NameField.ElementPrefixBox, Type = typeof(ListBox))]
    public class NameField : Control
    {
        private const String ElementPrefixBox        = "PART_PrefixBox";

        private static ObservableCollection<NamePrefix> _namePrefixes;

        static NameField()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(NameField), new FrameworkPropertyMetadata(typeof(NameField)));

            _namePrefixes = new ObservableCollection<NamePrefix>();
        }

        public static void AddNamePrefix(NamePrefix namePrefix)
        {
            lock (_namePrefixes)
            {
                _namePrefixes.Add(namePrefix);
            }
        }

        public static IEnumerator<NamePrefix> GetNamePrefixes()
        {
            return _namePrefixes.GetEnumerator();
        }

    }

    /// <summary>
    /// A Key/Value structure containing a Name Prefix ID and String value.
    /// </summary>
    public struct NamePrefix
    {
        public NamePrefix(Int32 id, String prefix)
            : this()
        {
            ID = id;
            Prefix = prefix;
        }

        public Int32 ID { get; set; }
        public String Prefix { get; set; }
    }

}

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MyWPF"
    xmlns:con="clr-namespace:MyWPF.Converters"
    >

    <Style TargetType="{x:Type local:NameField}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:NameField}">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock TextWrapping="NoWrap" Text="Name:" VerticalAlignment="Center" Margin="3" />
                        <ListBox x:Name="PART_PrefixBox" VerticalAlignment="Center" Margin="3" >
                            <ListBox.ItemBindingGroup>
                                <BindingGroup Name="NamePrefixes"/>
                            </ListBox.ItemBindingGroup>
                        </ListBox>
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

【问题讨论】:

    标签: c# wpf binding listbox observablecollection


    【解决方案1】:

    现在,我不确定你在做什么,因为你的类扩展了 Control,所以我假设你正在创建一个自定义控件,所以我的回答是基于此。我还假设 NamePrefixes 永远不会改变,这就是你使用静态的原因。

    我会跳过静态并这样做:

    public class NameField : Control
    {
        private const String ElementPrefixBox        = "PART_PrefixBox";
    
        public ObservableCollection<NamePrefix> NamePrefixes {get;private set;}
        public NameField()
        {
            NamePrefixes = new ObservableCollection<NamePrefix>();
        }
    }
    
    <Style TargetType="{x:Type local:NameField}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:NameField}">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock TextWrapping="NoWrap" Text="Name:" VerticalAlignment="Center" Margin="3" />
                        <ListBox x:Name="PART_PrefixBox" 
                            VerticalAlignment="Center" 
                            Margin="3" 
                            ItemsSource="{Binding NamesPrefix, RelativeSource={RelativeSource FindAncestor, Ancestortype=Whatever}}" />
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    您将 ItemsSource 绑定到自定义控件的根(无法从您的代码中看出它是什么)。您也许可以将名称应用于您的根目录,然后只需使用ElementName=,IIRC 有时会起作用。

    如果您绝对需要将其设为静态,因为所有控件都必须在其中任何一个更新时更新,那么您可以将可观察集合设为静态并将 ItemsSource 绑定到 {x:Static local:NameField.NamesPrefix}。只要意识到您只能绑定到公共属性,而不是字段或方法(不使用对象数据源或其他东西)。

    【讨论】:

      猜你喜欢
      • 2011-02-22
      • 1970-01-01
      • 2011-05-07
      • 1970-01-01
      • 1970-01-01
      • 2022-12-11
      • 1970-01-01
      • 2015-06-03
      • 1970-01-01
      相关资源
      最近更新 更多