C# 是否将textblock绑定到XAML中键的字典值?

C# 是否将textblock绑定到XAML中键的字典值?,c#,wpf,xaml,C#,Wpf,Xaml,我有一个带有enum属性的模型(在本例中,与出口管制条例相关)。当向用户显示值时,我想显示相应的字符串。有时在ComboBox中(用户可以在其中选择值),有时在TextBlock中(只读) 例如:对于ExportRegulationType.EAR,我想显示“EAR”,而对于ExportRegulationType.DoNotExport,我想显示“不导出”。请注意,我没有任何语言本地化需求,但我认识到这个问题 目前,在我的ViewModel中,我有一个基于当前枚举值返回字符串的属性,还有另一个

我有一个带有enum属性的模型(在本例中,与出口管制条例相关)。当向用户显示值时,我想显示相应的字符串。有时在ComboBox中(用户可以在其中选择值),有时在TextBlock中(只读)

例如:对于
ExportRegulationType.EAR
,我想显示
“EAR”
,而对于
ExportRegulationType.DoNotExport
,我想显示
“不导出”
。请注意,我没有任何语言本地化需求,但我认识到这个问题

目前,在我的ViewModel中,我有一个基于当前枚举值返回字符串的属性,还有另一个返回
字典的属性。对于组合框,我可以将
ItemsSource
绑定到dictionary属性,对于TextBlocks,我可以绑定到string属性。这是可行的,但有点笨拙

两个问题:

1) 在我看来,我应该能够在XAML(可能在App.XAML中)中将字典(带有键和值)声明为静态资源,并将其用于ComboBox版本的ItemsSource。然而,我不知道如何声明和引用这样的东西。我该怎么做

2) 假设上面的内容已经就位,我想我还可以设置一个与textblock的绑定,因此基于enum属性,它将在字典中查找字符串

我已经看到了以下关于或枚举值的问题。第一个是不够的,第二个是没有回答

这些应该仅是XAML,并使我能够从我的ViewModel中删除这些方法(只有一个公开的
ExportRegulationType
enumerated属性)。这些方法可能吗

编辑:其他信息:


在应用程序中,我将有许多不同的视图、模型和视图模型集。但是,由于出口管制条例是一个常见且一致的要求,我使用合成来保持干燥。即,模型a和B都有一个出口管制模型。视图模型A1、A2、B1和B2将有一个出口管制视图模型。视图将ave控件绑定到其ViewModel的ExportControlViewModel。视图将有一个组合框或文本块,但不能同时有两个(取决于用户是否可以更改值).

我不知道这是否适用于您的情况,但这里有一个可能的解决方案。在您的视图模型中,公开ExportRegulationType属性,然后创建一个用于显示所需字符串的

首先创建您的价值转换器:

class ExportRegulationTypeToStringConverter: IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        ExportRegulationType regType = (ExportRegulationType)value;

        switch(regType)
        {
            case ExportRegulationType.EAR:
                return "EAR";
            case ExportRegulationType.DoNotExport:
                return "Do Not Export";

            //handle other cases
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter,    System.Globalization.CultureInfo culture)
    {
        return Binding.DoNothing;
    }

    #endregion
}
然后在xaml中添加对转换器的引用。local是类所在的命名空间

<local:ExportRegulationTypeToStringConverter x:Key="exportRegConverter" />

最后,设置文本框的值以使用转换器。pathToEnum是ExportRegulationType类型的ViewModel上公开的属性

<TextBlock Text="{Binding pathToEnum, Converter={StaticResource exportRegConverter}}" />

用于用枚举的值填充组合框

<Window.Resources>
 <ObjectDataProvider x:Key="dataFromEnum"
   MethodName="GetValues" ObjectType="{x:Type System:Enum}">
      <ObjectDataProvider.MethodParameters>
           <x:Type TypeName="local:ExportRegulationType"/>
      </ObjectDataProvider.MethodParameters>
 </ObjectDataProvider>
</Window.Resources>

现在,我们创建ComboBox并使用容器样式来显示枚举所需的字符串

<ComboBox ItemsSource="{Binding Source={StaticResource dataFromEnum}}">
    <ComboBox.ItemContainerStyle>
        <Style TargetType="ComboBoxItem">
            <Setter Property="Content" Value="{Binding Converter={StaticResource exportRegConverter}}" />
        </Style>
    </ComboBox.ItemContainerStyle>
</ComboBox>

使用 然后将组合框的项目绑定到它,并将“DisplayMemberPath”设置为“Value”

这应该做的是显示字典的值,但是在
SelectedValue
后面的代码中是一个
KeyValuePair

对于文本块,使用
ElementName=yourcombobox
Path=SelectedItem
使用
Binding

<TextBlock Text="{Binding SelectedItem, ElementName=yourcombobox}" />


让我知道它的进展情况=)

而不是
字典
你有另一个选择

见以下问题:

您可以像这样向枚举添加
Description
属性

public enum ExportRegulationType
{
    [Description("EAR")]
    EAR,
    [Description("Do Not Export")]
    DoNotExport
}
当您想要显示它时,您可以使用我链接的问题中找到的
EnumDescriptionConverter
Converter

它基于这样一个原则,即不同的枚举值不需要仅限于切换字符串。相反,您可以声明要表示每个值的任何UI片段(字符串、图像、不同控件和布局等),并使用附加的行为来控制其可见性

因此,可以将您的情况设置为具有两个不同的文本块,每个文本块绑定到类型为
ExportRegulationType
的相同属性。由于它们绑定到同一属性,因此它们的可见性是相互排斥的:

<Grid>
    <TextBlock
        Text="EAR"
        local:EnumVisibility.Value="{Binding ExportRegulationType}"
        local:EnumVisibility.TargetValue="EAR"
    />
    <TextBlock
        Text="Do Not Export"
        local:EnumVisibility.Value="{Binding ExportRegulationType}"
        local:EnumVisibility.TargetValue="DoNotExport"
        FontWeight="Bold"
    />
</Grid>
我们将每个项与一个枚举值关联,然后使用一个双向绑定到
EnumSelector.SelectedValue
,这样每当视图模型的属性发生变化时,它就会写回视图模型的属性


这提供了与文本块相同的灵活性:您可以根据需要决定如何设置文本以及每个项目所包含的内容。

我将@Dylan和@Meleak写的内容结合起来解决了这个问题。我将此作为一个答案来说明最终的解决方案是什么:

首先,我实现了一个IValueConverter(基于@Meleak的回答):

在我的App.xaml中,我声明了ObjectDataProvider以获取枚举值列表和EnumDisplayConverter(因为它们将由多个不同的视图使用):


[其他东西…]
对于文本块:

<TextBlock Text="{Binding Export.Regulation, Converter={StaticResource ExportDisplayConverter}}"/>

对于组合框:

<ComboBox ItemsSource="{Binding Source={StaticResource ExportRegulationValues}}"
          SelectedValue="{Binding Document.Export.Regulation}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Converter={StaticResource ExportDisplayConverter}}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>


这很好用

添加了C#作为标记,因此答案得到语法highlightingSlick。作为。真见鬼!我喜欢字符串定义与枚举一起嵌入,转换器(带有一个小的调整)对于任何枚举都是通用的,并且没有Description属性,非常优雅;我要赞扬你在正确的方向上行动迅速,需要更多的代表!哦,请注意:使用ComboBox.ItemContainerStyle几乎奏效了-th
public enum ExportRegulationType
{
    [Description("Not Determined")]
    NotDetermined,   // Export authority not determined

    EAR,            // Controlled by EAR Regulations

    ITAR,           // Controlled by ITAR Regulations

    [Description("Do Not Export")]
    DoNotExport,    // Export not allowed

    Unrestricted    // Export not controlled
}
<Application.Resources>
    [Other stuff...]
    <ObjectDataProvider MethodName="GetValues"
                        ObjectType="{x:Type sys:Enum}"
                        x:Key="ExportRegulationValues">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="models:ExportRegulationType"/>
        </ObjectDataProvider.MethodParameters>      
    </ObjectDataProvider>
    <local:EnumDescriptionConverter x:Key="ExportDisplayConverter"/>
</Application.Resources>
<TextBlock Text="{Binding Export.Regulation, Converter={StaticResource ExportDisplayConverter}}"/>
<ComboBox ItemsSource="{Binding Source={StaticResource ExportRegulationValues}}"
          SelectedValue="{Binding Document.Export.Regulation}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Converter={StaticResource ExportDisplayConverter}}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>