Я сошел с ума от привязки combobox к типизированному свойству перечисления класса, где само перечисление объявлено в том же классе.Связывание ComboBox с перечислением, вложенным в класс
Я пытаюсь выполнить приведенный здесь ответ (wpf combobox binding to enum what i did wrong?) В частности, я использую предложенный код MarkupExtension и соответствующий код xaml.
Мой рабочий код:
Определение Enum в отдельном файле.
namespace EnumTest
{
public enum TestEnum {one, two, three, four };
}
Класс, который использует Enum (Обратите внимание, что код PropertyChanged была удалена, чтобы упростить вещи):
namespace EnumTest
{
public class Test : INotifyPropertyChanged
{
private TestEnum _MyVar;
public TestEnum MyVar {
get { return _MyVar; }
set
{
_MyVar = value;
OnPropertyChanged("MyVar");
}
}
public Test()
{
_MyVar = TestEnum.three;
}
}
}
файл программы, который использует класс:
namespace EnumTest
{
public partial class Window1 : Window
{
Test _oTest = new Test();
public Window1()
{
InitializeComponent();
cmbBox.DataContext = _oTest;
}
}
}
метод расширения для отображение Enum
namespace EnumTest
{
[MarkupExtensionReturnType(typeof(object[]))]
public class EnumValuesExtension : MarkupExtension
{
public EnumValuesExtension()
{
}
public EnumValuesExtension(Type enumType)
{
this.EnumType = enumType;
}
[ConstructorArgument("enumType")]
public Type EnumType { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (this.EnumType == null)
throw new ArgumentException("The enum type is not set");
return Enum.GetValues(this.EnumType);
}
}
}
И код XAML, который используется для отображения данных:
<Window x:Class="EnumTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:w="clr-namespace:EnumTest"
Title="Window1" Height="300" Width="300">
<Grid>
<ComboBox Name="cmbBox"
Height="20"
Width="80"
ItemsSource="{Binding Source={w:EnumValues EnumType=w:TestEnum}}"
SelectedItem="{Binding Path=MyVar}"
/>
</Grid>
</Window>
выше все хорошо и денди, но я хочу, чтобы определить Enum в класс Test и канавы Enum от определяемого на глобальный охват. Как так:
namespace EnumTest
{
public class Test : INotifyPropertyChanged
{
// Declare Enum **INSIDE** the class
public enum TestEnum {one, two, three, four };
private TestEnum _MyVar;
public TestEnum MyVar {
get { return _MyVar; }
set
{
_MyVar = value;
OnPropertyChanged("MyVar");
}
}
public Test()
{
_MyVar = TestEnum.three;
}
}
}
Так вопрос я говорил ссылается на синтаксис XAML согласования, как существа:
<ComboBox Name="cmbBox"
...
ItemsSource="{Binding Source={w:EnumValues EnumType=w:Test+TestEnum}}"
...
/>
Но это (вроде) не работает для меня. Когда я сделать чистую сборку, я получаю «Build преуспели» сообщение в строке состояния VS 2008, но я получаю сообщение об ошибке сообщается в XAML
Type 'Test+TestEnum' was not found.
Но код работает, как ожидалось!
Однако это означает, что конструктор xaml не загружается. Таким образом, я как бы прикручен к работе wpf, пока не могу очистить ошибку xaml.
Теперь я задаюсь вопросом, является ли это проблемой VS 2008 SP1, а не проблемой с моей стороны.
Редактировать
- Сделано моя проблема утверждение более явным.
- Пробовал 1-решение Джоэла, но я в конечном итоге с кодом, исполняемым и 2 ошибки Xaml
- 2 варианта Пробовал Джоэл и работал прямо из коробки - так что я буду с этим один!
Примечание Так вопрос, который я получил код MarkupExtension от использования этого стиля синтаксиса для XAML:
<ComboBox ItemsSource="{w:EnumValues w:TestEnum}"/>
Когда я использую, что я получаю ошибку компиляции, говоря, что конструктор EnumValues не принимает 1 параметр. Я сделал некоторый googling, и это, кажется, ошибка в VS. Я использую VS 2008 SP1. Я видел некоторые комментарии, которые ссылались на него в бета-версии VS 2010. Во всяком случае, поэтому я использую синтаксис xaml
<ComboBox ItemsSource="{w:EnumValues EnumType=w:TestEnum}"/>
Поскольку этот синтаксис работает!
Что касается ошибки в конструкторе, то это происходит только в дизайнере.В противном случае он должен работать нормально. Чтобы избежать этой ошибки, определите расширение разметки в отдельном сборке –
@Thomas: Я забыл, как дизайнер может быть проворным в отношении того, какие типы создаются, когда/где и как он их создает. –
@Joel - И новички программисты wpf знают это как? Знание ставить класс в отдельную сборку, чтобы удовлетворить одну часть инструмента построения, довольно неясно ИМХО. Но я буду продолжать показываться, пока не получу разумное понимание. Еще раз спасибо. –