I am still getting used to MVVM so if there is a better way to do this let me know. I do have to stick to a certain way of doing things so everything at the company I work at stays somewhat standard.I am trying to populate a combobox with the descriptions from my Enum class. I think this is an easy task, but I am not sure how to go about it. Any help is appreciated. If you need more code or information, please let me know. Code is below.
I have my Descriptions in a class called 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
}
In my viewmodel I have the code to fill my combobox:
public IEnumerable<ArTypes> GetAllArTypesData()
{
try
{
// I believe the logic for setting the IEnumerable would go here
}
catch (Exception ex)
{
LogException(ex);
}
return null;
}
To populate the combobox I am running this:
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);
}
}
Here is where the data is loaded onto the 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}" />
If you're asking how to collect the values from the DescriptionAttribute
on each enum
instance, you can do it something like this:
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);
}
There could be an error in there somewhere as I can't test this out at the moment, so please let me know if there is.