Я не знаю о простом подходе, основанном на XAML, который сопоставляет значение одного типа со значением другого типа. Однако:
- По умолчанию привязки в WPF из
enum
типа в текстовый объект, как TextBlock.Text
, Button.Content
и т.д. будет использовать имя enum
значение. В этом случае вам нечего делать. Имя значения будет отображаться как связанное значение автоматически.
- Если по какой-либо причине вы привязываетесь не к тому, что действительно набирается как
enum
, но как простой int
, вы должны иметь возможность реализовать IValueConverter
, который выполняет сопоставление и которое вы используете в объявлении привязки экранного объекта ,
Если вы обеспечите a good, minimal, complete code example, который показывает существенную часть вашего связывания (т.е. типа enum
и некоторые XAML, который показывает его), можно было бы предусмотреть более конкретный ответ.
EDIT:
К сожалению, пример кода в вопросе не является полным. Тем не менее, обращаясь к тому, что, по-видимому, представляет собой пару основных проблем & hellip;
«Я не знаю, как связать перечисление с ComboBox еще»
Это «просто работает». Например, вот простая форма XAML с TextBlock
, чтобы отобразить текущее значение перечисления в MainWindow
объекте, и ComboBox
, где свойство Tag
присваиваются само значение перечисления, как это Content
свойство:
<StackPanel>
<TextBlock Text="{Binding ElementName=mainWindow, Path=Value}" />
<ComboBox SelectionChanged="ComboBox_SelectionChanged" SelectedValuePath="Tag">
<ComboBoxItem Tag="{x:Static local:Fruit.Apple}" Content="{x:Static local:Fruit.Apple}" />
<ComboBoxItem Tag="{x:Static local:Fruit.Orange}" Content="{x:Static local:Fruit.Orange}" />
<ComboBoxItem Tag="{x:Static local:Fruit.Banana}" Content="{x:Static local:Fruit.Banana}" />
<ComboBoxItem Tag="{x:Static local:Fruit.Kiwi}" Content="{x:Static local:Fruit.Kiwi}" />
</ComboBox>
</StackPanel>
(Предположим, объявлен enum Fruit { Apple, Orange, Banana, Kiwi }
, конечно)
Примечание синтаксис для использования конкретных значений enum
: {x:Static local:Fruit.Apple}
.local
относится к пространству имен enum
, которое объявлено в атрибуте xmlns
для корневого элемента XAML (например, любое пространство имен XAML), и, конечно, значение enum
указано как указано в C# (то есть <enum name>.<enum value>
).
TextBlock
связывается непосредственно в собственности, имеющей тип Fruit
.
Часть XAML составитель и WPF выполнение обрабатывать все остальное, преобразование enum
значения их имена, когда они отображаются пользователю, в то время как с использованием фактических enum
значения при работе со значениями в коде.
Window
класс выглядит следующим образом:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public Fruit Value
{
get { return (Fruit)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(Fruit), typeof(MainWindow), new PropertyMetadata(Fruit.Apple));
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBox comboBox = (ComboBox)sender;
Value = (Fruit)comboBox.SelectedValue;
}
}
Т.е. a нормальное свойство DependencyProperty
и обработчик события для обновления значения свойства, когда выбран конкретный ComboBoxItem
.
Непонятно из вашего примера кода, как настроен ваш DataAdapter
. Но, надеюсь, он настроен на автоматическое преобразование целого числа в БД в значение типа enum
в строке. Это было бы идеально, так как тогда вы можете просто привязать представление таблицы непосредственно к объекту интерфейса WPF.
Если он не настроен таким образом, я бы сосредоточил ваше внимание на этом. Но если вы действительно хотите, вы должны добавить IValueConverter
в привязку, используемую для отображения строк таблицы в вашем WPF-интерфейсе. Опять же, с вопросом, не имеющим каких-либо подробностей относительно areaListGrid
, я не могу сказать, как именно вы это сделаете. Но он будет работать, как и любой другой IValueConverter
: просто напишите конвертер для сопоставления с int
в данных БД на имя enum
и используйте это в любом связывании, которое у вас есть для столбца БД для этого значения.
EDIT # 2:
Если вы на самом деле не используется enum
типа, вы можете реализовать IValueConverter
для обработки явного преобразования. Например:
class Int32ToValueNameConverter : IValueConverter
{
private static readonly Dictionary<int, string> _intToName = new Dictionary<int, string>()
{
{ 0, "Apple" },
{ 1, "Orange" },
{ 2, "Banana" },
{ 3, "Kiwi" },
};
private static readonly Dictionary<string, int> _nameToInt = _intToName.ToDictionary(kvp => kvp.Value, kvp => kvp.Key);
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is int && targetType == typeof(string))
{
string result;
if (_intToName.TryGetValue((int)value, out result))
{
return result;
}
}
return Binding.DoNothing;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
string text = value as string;
if (text != null && targetType == typeof(int))
{
int result;
if (_nameToInt.TryGetValue(text, out result))
{
return result;
}
}
return Binding.DoNothing;
}
}
Вы можете использовать выше в XAML как это:
<StackPanel>
<Button Content="Increment Int" Click="Int32Button_Click" HorizontalAlignment="Left" />
<TextBlock>
<TextBlock.Text>
<Binding ElementName="mainWindow" Path="Int32Value">
<Binding.Converter>
<local:Int32ToValueNameConverter />
</Binding.Converter>
</Binding>
</TextBlock.Text>
</TextBlock>
<TextBox>
<TextBox.Text>
<Binding ElementName="mainWindow" Path="Int32Value" UpdateSourceTrigger="PropertyChanged">
<Binding.Converter>
<local:Int32ToValueNameConverter />
</Binding.Converter>
</Binding>
</TextBox.Text>
</TextBox>
</StackPanel>
При нажатии кнопки будет вращаться через целые значения, показывая результат в обоих TextBlock
и TextBox
. Ввод допустимого значения в TextBox
приведет к обновлению связанного свойства, которое, конечно же, обновит TextBlock
, чтобы отразить это изменение.
код-позади, чтобы поддержать приведенный выше пример:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public int Int32Value
{
get { return (int)GetValue(Int32ValueProperty); }
set { SetValue(Int32ValueProperty, value); }
}
public static DependencyProperty Int32ValueProperty =
DependencyProperty.Register("Int32Value", typeof(int), typeof(MainWindow), new PropertyMetadata(0));
private void Int32Button_Click(object sender, RoutedEventArgs e)
{
int newValue = Int32Value + 1;
if (newValue > 3)
{
newValue = 0;
}
Int32Value = newValue;
}
}
Я надеюсь, что вы можете применить в приведенном выше примере связывания вашего собственного DataGrid
сценария и простите, что я не чувствую, что собирается усилие производства автономный пример DataGrid
, который должен иметь ваш вопрос, и на котором я мог бы основывать ответ, если бы он был предоставлен.
Спасибо! Я обновил код.Я использовал 'int' как тип данных, и я знаю, что это может быть не самая лучшая практика, но я не знаю, как привязать' enum' к ComboBox. – leetom
@leetom: см. Мое редактирование выше –
Большое спасибо за ваше терпение. Я могу сделать ошибку, упомянув перечисление. На самом деле я вообще не использовал тип «enum» (потому что сначала не думаю, что мне нужно), все, что я сделал, это попытка показать имена (строки) пользователю и сохранить данные как «целочисленные» в кода и базы данных. Это то, что я обычно делаю, когда я использую динамический типизированный язык. Но теперь в C# я не могу напрямую изменить поле 'integer' на' string'. Я пытаюсь реализовать «IValueConverter», все это новое, потому что я все еще новичок. – leetom