将Enum描述放在IEnumerable和ComboBox中

时间:2013-11-15 14:50:54

标签: c# wpf xaml mvvm enums

我仍然习惯MVVM,所以如果有更好的方法,请告诉我。我必须坚持某种做事方式,所以我工作的公司的一切都保持一定的标准。我正在尝试使用我的Enum类中的描述填充组合框。我认为这是一项简单的任务,但我不知道该怎么做。任何帮助表示赞赏。如果您需要更多代码或信息,请告诉我们。代码如下。

我在一个名为Enum.cs的类中有我的描述:

[TypeConverter(typeof(EnumToStringUsingDescription))]    
    public enum ArTypes
    {
        [Description("(All)")]
        arAll = 0,
        [Description("Adjustment")]
        [EnumInformation("Adjustment", true, 1)]
        arAdjustment = 1,
        [Description("Payment")]
        [EnumInformation("Payment", true, 2)]
        arPayment = 3,
        [Description("Deposit Receipt")]
        [EnumInformation("Deposit Receipt", true, 3)]
        arDepositReceipt = 5,
        [Description("Deposit Applied")]
        [EnumInformation("Deposit Applied", true, 4)]
        arDepositApplied = 7,
        [Description("Bad Debt Transfer")]
        [EnumInformation("Bad Debt Transfer", true, 5)]
        arBadDebtTransfer = 9,
        [Description("Bad Debt Writeoff")]
        [EnumInformation("Bad Debt Writeoff", true, 6)]
        arBadDebtWriteoff = 11,
        [Description("Bad Debt Recovery")]
        [EnumInformation("Bad Debt Recovery", true, 7)]
        arBadDebtRecovery = 13,
        [Description("Charge")]
        [EnumInformation("Charge", true, 8)]
        arCharge = 15,
        [Description("Immediate Case Receipt")]
        [EnumInformation("Immediate Cash Receipt", true, 9)]
        arImmediateCashReceipt = 17,
        [Description("Over Payment")]
        [EnumInformation("Over Payment", true, 10)]
        arOverPayment = 19,
        [Description("Balance Forward")]
        [EnumInformation("Balance Forward", true, 11)]
        arBalanceForward = 21
    }

在我的viewmodel中,我有填充组合框的代码:

public IEnumerable<ArTypes> GetAllArTypesData()
        {
            try
            {
              //I believe the logic for setting the Ienumberable would go here


            }
            catch (Exception ex)
            {
                LogException(ex);
            }
            return null;
        }

要填充我正在运行的组合框:

void PopulateComboLists()
        {
            CycleList = new ObservableCollection<Cycle>();
            ServiceTypeList = new ObservableCollection<ServiceType>();
            RateList = new ObservableCollection<Rate>();
            CustomerTypeList = new ObservableCollection<CustomerType>();
            ArCodeList = new ObservableCollection<Arcode>();
            ArTypeList = new ObservableCollection<ArTypes>();

            CycleList.Add(new Cycle() { CycleID = -1, CycleDescription = "(All)" });
            ServiceTypeList.Add(new ServiceType() { ServiceTypeID = -1, ServiceDescription = "(All)" });
            CustomerTypeList.Add(new CustomerType() { CustomerTypeID = -1, Description = "(All)" });
            ArCodeList.Add(new Arcode() { ArcodeID = -1, Description = "(All)" });

            foreach (var item in cycles)
            {
                CycleList.Add(item);
            }

            foreach (var item in serviceTypes)
            {
                ServiceTypeList.Add(item);
            }

            foreach (var item in rates)
            {
                RateList.Add(item);
            }

            foreach (var item in custTypes)
            {
                CustomerTypeList.Add(item);
            }

            foreach (var item in arCodes)
            {
                ArCodeList.Add(item);
            }

            foreach (var item in arTypes)
            {
                ArTypeList.Add(item);
            }
        }

以下是将数据加载到UI的位置:

protected override void LoadDataStart()
        {
            //*Insert IsBusy and any other logic needed before database calls*//
            this.IsBusy = true;
            this.BusyMessage = "Generating Widget...";

            try
            {
                //*Create a method for each database call - start a new task for each*//
                var taskCTR = Task.Factory.StartNew(() => GetAllCustomerTypeReportsData()).ContinueWith(results => GetAllCustomerTypeReportsDataContinue(results.Result));
                var taskST = Task.Factory.StartNew(() => GetAllServiceTypesData()).ContinueWith(results => GetAllServiceTypesDataContinue(results.Result));
                var taskRL = Task.Factory.StartNew(() => GetAllRatesData()).ContinueWith(results => GetAllRatesDataContinue(results.Result));
                var taskCL = Task.Factory.StartNew(() => GetAllCyclesData()).ContinueWith(results => GetAllCyclesDataContinue(results.Result));
                var taskCT = Task.Factory.StartNew(() => GetAllCustomerTypesData()).ContinueWith(results => GetAllCustomerTypesDataContinue(results.Result));
                var taskAC = Task.Factory.StartNew(() => GetAllArCodesData()).ContinueWith(results => GetAllArCodesDataContinue(results.Result));
                var taskAT = Task.Factory.StartNew(() => GetAllArTypesData()).ContinueWith(results => GetAllArTypesDataContinue(results.Result));

                Task[] allTasks = new Task[7] { taskCTR, taskST, taskRL, taskCL, taskCT, taskAC, taskAT };

                Task.Factory.ContinueWhenAll(allTasks, loadDataContinue =>
                {
                    Action executeContinue = () =>
                    {
                        PopulateComboLists();

                        if (CanLoad)
                        {
                            LoadDataContinue();
                            IsBusy = false;
                        }
                        else
                            ShowOptionsView();
                    };
                    this.UIDispatcher.Invoke(executeContinue);
                });
            }
            catch (Exception ex)
            {
                LogException(ex);
            }

            //*Base class will call LoadDataContinue() once the database calls are complete*//
        }

XAML:

<Label VerticalAlignment="Center" Margin="5,0,0,0" Content="ArType: " Grid.Row="5" Grid.Column="0"></Label>
        <telerik:RadComboBox ItemsSource="{Binding ArTypeList}"
                             DisplayMemberPath="Key"
                             SelectedValuePath="Value"
                             HorizontalAlignment="Left" Width="190"
                             SelectedValue="{Binding Path=SelectedArType, Mode=TwoWay, ValidatesOnDataErrors=True}" 
                             TabIndex="5"  Grid.Row="5" VerticalAlignment="Center" Grid.Column="1"
                             Style="{StaticResource RadComboBoxStyle}" />

2 个答案:

答案 0 :(得分:1)

如果您询问如何从每个DescriptionAttribute实例上的enum收集值,您可以这样做:

ObservableCollection descriptions = new ObservableCollection();
foreach (object instance in Enum.GetValues(typeof(ArTypes)))
{
    FieldInfo fieldInfo = typeof(ArTypes).GetField(instance.ToString());
    object[] customAttributes = 
        fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
    if (customAttributes != null && customAttributes.Length > 0)
        descriptions.Add(((DescriptionAttribute)customAttributes[0]).Description);
}

因为我现在无法测试,所以可能会出现错误,所以如果有,请告诉我。

答案 1 :(得分:1)

这可以通过使用comboBox的转换器和项目模板来完成。

这是转换器代码,当绑定到枚举时将返回Description值:

namespace Focal.FirmwareUpdate.UI.WPF.Common.Converters
{
    public class EnumDescriptionConverter : IValueConverter
    {
        private string GetEnumDescription(Enum enumObj)
        {
           FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());

           object[] attribArray = fieldInfo.GetCustomAttributes(false);

           if (attribArray.Length == 0)
           {
               return enumObj.ToString();
           }
           else
           {
               DescriptionAttribute attrib = attribArray[0] as DescriptionAttribute;
               return attrib.Description;
           }
       }

       object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
       {
           Enum myEnum = (Enum)value;
           string description = GetEnumDescription(myEnum);
           return description;
       }

       object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
       {
           return string.Empty;
       }
   }

然后在你的xaml中你需要使用和项目模板。

<ComboBox Grid.Row="1" Grid.Column="1"  Height="25" Width="100" Margin="5"
                  ItemsSource="{Binding Path=MyEnums}"
                  SelectedItem="{Binding Path=MySelectedItem}"
                  >
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Converter={StaticResource enumDescriptionConverter}}"/>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>