我不确定如何准确地解决这个问题。我在NameField.cs类中有一个静态的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>
答案 0 :(得分:3)
现在,我不确定你正在做什么,因为你的类扩展了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它有时会起作用。
如果您绝对需要将其设置为静态,因为必须在更新其中任何一个控件时更新所有控件,那么您可以使observable collection静态并将ItemsSource绑定到{x:Static local:NameField.NamesPrefix}。只是意识到你只能绑定到公共属性,而不能绑定到字段或方法(不使用对象数据源或其他东西)。