Hi I need to narrow down the search string to allow users to put some flags at the end of search like "/A" or "/W". This is wpf and MVVM. I tried to put it in the property but it looks like it doesn't work. Where should I put it if I can't put it in the property.
public NavDataType Type
{
get
{
return _type;
}
set
{
if (_type.ToString().Substring(_type.ToString().Length - 2, 2) == "/A")
_type = NavDataType.Airport;
if (_type.ToString().Substring(_type.ToString().Length - 2, 2) == "/W")
_type = NavDataType.Waypoint;
if (_type.ToString().Substring(_type.ToString().Length - 2, 2) == "/N")
_type = NavDataType.Navaid;
SetProperty(ref _type, value, "Type");
}
}
if (_type.ToString().Substring(_type.ToString().Length - 2, 2) == "/N")
_type = NavDataType.Navaid;
SetProperty(ref _type, value, "Type");
the problem is that you're setting _type in the if statements (works correcty), but then the SetProperty call is overwriting that with whatever value was when it got passed in.
Related
I have the following method to save order properties on a purchase order:
public void SetOrderProperty(string orderPropertyName, string value)
{
PurchaseOrder purchaseOrder = TransactionLibrary.GetBasket().PurchaseOrder;
OrderProperty orderProperty = purchaseOrder.OrderProperties.FirstOrDefault(x => x.Key == orderPropertyName);
if (orderProperty != null)
{
orderProperty.Value = value;
orderProperty.Save();
}
else
{
OrderProperty op = new OrderProperty
{
Key = orderPropertyName,
Value = value,
Order = purchaseOrder
};
op.Save();
}
purchaseOrder.Save();
TransactionLibrary.ExecuteBasketPipeline();
}
When I save a value using this I can see it appear against the order in the uCommerce_OrderProperty table.
However, with some properties, when I try to read them back out they are missing:
public string GetOrderProperty(string orderPropertyName)
{
PurchaseOrder purchaseOrder;
using (new CacheDisabler())
{
purchaseOrder = TransactionLibrary.GetBasket().PurchaseOrder;
}
OrderProperty orderProperty = purchaseOrder.OrderProperties.FirstOrDefault(x => x.Key == orderPropertyName);
if (orderProperty != null)
{
return orderProperty.Value;
}
return string.Empty;
}
I have also tried this code from the uCommerce site:
public string GetOrderProperty(string orderPropertyName)
{
PurchaseOrder purchaseOrder = SiteContext.Current.OrderContext.GetBasket().PurchaseOrder;
return purchaseOrder[orderPropertyName];
}
If I inspect purchaseOrder I can see the OrderProperties are missing. I have 7 properties at any one time but purchaseOrder only ever seems to have a max of 5 even though there is 7 in the table.
These are Order Properties and not Order Line Properties. Can anyone give me any pointers as to why I am seeing this behaviour?
EDIT
This line does get the value I am looking for:
OrderProperty op = OrderProperty.FirstOrDefault(x => x.Order.OrderId == purchaseOrder.OrderId && x.Key == orderPropertyName);
Even when this line (called the line after) returns null:
OrderProperty orderProperty = purchaseOrder.OrderProperties.FirstOrDefault(x => x.Key == orderPropertyName);
(Both are looking for the same Order Property)
Can anyone tell me why?
I have a comment, but I'm not allowed because of missing reputation.
Everything seems to be fine regarding your code. Can I persuade you to show the
uCommerce_OrderProperty table?
- I just want to check that the OrderLineId column is empty for you order properties.
You should be able to set and get it like this:
var property = order[orderPropertyName];
order[orderPropertyName] = "VALUE";
Regards
Mads
We also recommend that Ucommerce related question is posted at http://eureka.ucommerce.net/, the response time is often faster.
I made a simple dynamic object:
class Row
{
Dictionary<string, object> properties = new Dictionary<string, object>();
private int rIndex;
public Row(int rIndex)
{
this.rIndex = rIndex;
}
public object this[string name]
{
get
{
if (properties.ContainsKey(name))
{
return properties[name];
}
return null;
}
set
{
properties[name] = value;
}
}
public int RIndex
{
get { return rIndex; }
set { rIndex = value; }
}
}
I get the coloumn that i use to group from a configuration file.
Group by different value for example like this :
var t = lst.GroupBy(x => new { x1 = x["job"], x2 = x["schema"], x3 = x["line"], x4 = x["plant"], x5 = x["mod"], x6 = x["tag"] }).Select(g => new { g.Key.x1, g.Key.x2, g.Key.x3, g.Key.x4, g.Key.x5, g.Key.x6, });
this works well but i think it's too static.
How can i implement a dynamic Group by clause?
Is it possible, inside the Group By clause, get the Dictionary key value that is inside the dynamic object?
Thanks all in advance.
Okay, I think it probably makes sense to have something like a RowView class, which contains a reference to a Row, and the properties you're interested in (a subset of the row's properties). You can then make it implement IEquatable<RowView>, such that two RowView objects are equal if and only if:
They contain the same properties, in the same order
The property values are the same in the rows they refer to
For convenience, I'd probably add a CreateView(IEnumerable<string> properties) method to Row, so you can call:
var t = lst.GroupBy(x => x.CreateView(groupingProperties));
(I'd also advise using an automatically-implemented property for RIndex to simplify the code - and ideally rename it, as it's not clear what it's for at the moment.)
I have a form where I collect data from users. When this data is collected, I pass it to various partners, however each partner has their own rules for each piece of data, so this has to be converted. I can make this happen, but my worries are about the robustness. Here's some code:
First, I have an enum. This is mapped to dropdown a dropdown list - the description is the text value, and the int mapped to the value.
public enum EmploymentStatusType
{
[Description("INVALID!")]
None = 0,
[Description("Permanent full-time")]
FullTime = 1,
[Description("Permanent part-time")]
PartTime = 2,
[Description("Self employed")]
SelfEmployed = 3
}
When the form is submitted, the selected value is converted to its proper type and stored in another class - the property looks like this:
protected virtual EmploymentStatusType EmploymentStatus
{
get { return _application.EmploymentStatus; }
}
For the final bit of the jigsaw, I convert the value to the partners required string value:
Dictionary<EmploymentStatusType, string> _employmentStatusTypes;
Dictionary<EmploymentStatusType, string> EmploymentStatusTypes
{
get
{
if (_employmentStatusTypes.IsNull())
{
_employmentStatusTypes = new Dictionary<EmploymentStatusType, string>()
{
{ EmploymentStatusType.FullTime, "Full Time" },
{ EmploymentStatusType.PartTime, "Part Time" },
{ EmploymentStatusType.SelfEmployed, "Self Employed" }
};
}
return _employmentStatusTypes;
}
}
string PartnerEmploymentStatus
{
get { return _employmentStatusTypes.GetValue(EmploymentStatus); }
}
I call PartnerEmploymentStatus, which then returns the final output string.
Any ideas how this can be made more robust?
Then you need to refactor it into one translation area. Could be something like a visitor pattern implementation. Your choices are distribute the code (as you are doing now) or visitor which would centralize it. You need to build in a degree of fragility so your covering tests will show problems when you extend in order to force you to maintain the code properly. You are in a fairly common quandry which is really a code organisational one
I did encounter such a problem in one of my projects and I solved it by using a helper function and conventions for resource names.
The function is this one:
public static Dictionary<T, string> GetEnumNamesFromResources<T>(ResourceManager resourceManager, params T[] excludedItems)
{
Contract.Requires(resourceManager != null, "resourceManager is null.");
var dictionary =
resourceManager.GetResourceSet(culture: CultureInfo.CurrentUICulture, createIfNotExists: true, tryParents: true)
.Cast<DictionaryEntry>()
.Join(Enum.GetValues(typeof(T)).Cast<T>().Except(excludedItems),
de => de.Key.ToString(),
v => v.ToString(),
(de, v) => new
{
DictionaryEntry = de,
EnumValue = v
})
.OrderBy(x => x.EnumValue)
.ToDictionary(x => x.EnumValue, x => x.DictionaryEntry.Value.ToString());
return dictionary;
}
The convention is that in my resource file I will have properties that are the same as enum values (in your case None, PartTime etc). This is needed to perform the Join in the helper function which, you can adjust to match your needs.
So, whenever I want a (localized) string description of an enum value I just call:
var dictionary = EnumUtils.GetEnumNamesFromResources<EmploymentStatusType>(ResourceFile.ResourceManager);
var value = dictionary[EmploymentStatusType.Full];
I have defined an enum like
public Enum CompanyQuarters
{
First=1,
Second=2,
Third=3,
Fourth=4
}
I bind them to dropdown list like
ddlCompQuarter.DataSource = Enum.GetNames(typeof(CompanyQuarters));
ddlCompQuarter.DataBind();
Now I want to fetch the dropdownlist selected value For e.g for selection 'second' I like to fetch 2 ?
This does not work
int selectedVal = int.Parse(ddlCompQuarter.SelectedValue.ToString());
ActiveQuarters value = (ActiveQuarters)Enum.Parse(typeof(ActiveQuarters),ddlCompQuarter.SelectedValue.ToString());
or if you are using Dot Net Framework 4 or greater, see Enum.TryParse
ActiveQuarters value;
Enum.TryParse<ActiveQuarters>(ddlCompQuarter.SelectedValue.ToString(), out value);
Here I am showing you the best way to use enum:
public enum enumVIPBusinessPlanPaymentType {
[Description("Monthly")]
Monthly = 1,
[Description("Paid In Full (PIF)")]
PaidInFull = 2,
[Description("Barter")]
Barter = 3 }
and create a EnumHelper.cs class to read its value or description
public static Int32 GetIntValue(Enum en)
{
Type type = en.GetType();
return TemplateControlExtension.GetInt32(null, en);
}
public static string GetStringNameFromValue(Enum en)
{
Type type = en.GetType();
MemberInfo[] info = type.GetMember(en.ToString());
if (info != null && info.Length > 0)
{
object[] attrs = info[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attrs != null && attrs.Length > 0)
{
return ((DescriptionAttribute)attrs[0]).Description;
}
}
return TemplateControlExtension.GetString(null, en);
}
I hope it will like you
ActiveQuarters typedValue = (ActiveQuarters)Enum.Parse(typeof(ActiveQuarters),
ddlCompQuarter.SelectedValue);
// If you need numeric value
int numericValue = (int)typedValue;
CompanyQuarters comp= (CompanyQuarters)Enum.Parse(ddlCompQuarter.SelectedValue);
You can use Enum.Parse
var val = (int)(ActiveQuarters)Enum.Parse(typeof(ActiveQuarters),
ddlCompQuarter.SelectedValue.ToString());
Also I think your code has problem, you defined ActiveQuarters enum and you bind CompanyQuarters!.
You have to reverse the way you got the names in there.
http://blogs.msdn.com/b/tims/archive/2004/04/02/106310.aspx
you need to use Enum.Parse and then you can get your enum from ComboBox
You have to set text and value property at time of binding the drop down.
For value field you can use
Enum.GetValues(typeof(EnumProvider.CompanyQuarters))
I've created a SelectList from a enum. The enum has a description, and the int value is being set to the value I want to store in the database.
The problem is, the default (BLANK) I set on construction isn't being used.
This is my enum:
public enum Stage
{
[Description("")]
BLANK = -99,
[Description("No Data")]
NoData = 9999,
[Description("Nil")]
Nil = 0,
[Description("Action")]
SAction = 1,
[Description("Action Plus")]
SActionPlus = 2,
[Description("Full")]
Full = 3
}
I create it in my controller:
private static IEnumerable<SelectListItem> GenerateSenStageList()
{
var values = from Stage e in Enum.GetValues(typeof(Stage))
select new { ID = (int)e, Name = e.ToDescription() };
return new SelectList(values, "Id", "Name", (int)Stage.BLANK);
}
Where I thought the final parameter set the selected item.
I assign it as ViewData, and access it like:
<%= Html.DropDownList("Stage", (IEnumerable<SelectListItem>)ViewData["StageList"])%>
However, Nil is always the selected value.
What am I missing here??
Thanks!
The last parameter does determine the selected value. However, you are passing a Stage enumerated value as the last parameter, while the actual elements of your list are made up of an ID value and a Stage value. To make this work, you have to pass it the actual object from values with a Stage value of BLANK.
Iainie,
Using your code, i managed to get this working first time. here's my amended code (using the accountcontroller for testing) [using .net 3.5]:
// from account controller - put the enum, etc in there for brevity
public enum Stage
{
[Description("")]
BLANK = -99,
[Description("No Data")]
NoData = 9999,
[Description("Nil")]
Nil = 0,
[Description("Action")]
SAction = 1,
[Description("Action Plus")]
SActionPlus = 2,
[Description("Full")]
Full = 3
}
public static IEnumerable<SelectListItem> GenerateSenStageList()
{
var values = from Stage e in Enum.GetValues(typeof(Stage))
select new { ID = (int)e, Name = e.ToDescription() };
var sellist= new SelectList(values, "Id", "Name", (int)Stage.BLANK);
return sellist;
}
public virtual ActionResult LogOn()
{
var res = GenerateSenStageList();
ViewData["StageList"] = res;
return View();
}
// the ToDescription() extension method
public static class Extn
{
public static string ToDescription(this Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
var attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(
typeof(DescriptionAttribute),
false);
if (attributes != null &&
attributes.Length > 0)
return attributes[0].Description;
else
return value.ToString();
}
}
// then in the LogOn view:
<%= Html.DropDownList("Stage", (IEnumerable<SelectListItem>)ViewData["StageList"])%>
this all works exactly as you'd hoped for, so I'm wondering if your invocation from the view is somehow getting a bit fuddled. try my example above and see if there are any subtle differences in the selectlist generated code etc.
Just a guess, but:
You cast the ViewData["StageList"] to IEnumerable<SelectListItem>. That enumerable may be the SelectList that you created in the Controller, but it does not have the SelectedValue property.
Maybe it works if you cast ViewData["StageList"] to SelectList instead?
<%= Html.DropDownList("Stage", (SelectList)ViewData["StageList"])%>
In this case using the interface may be the wrong thing, because you actually need the information provided by the SelectList object.
#Ken Wayne VanderLinde is right. If you are using C# 4.0, then you can do this to populate the selected value:
private static IEnumerable<SelectListItem> GenerateSenStageList()
{
var values = from Stage e in Enum.GetValues(typeof(Stage))
select new { ID = (int)e, Name = e.ToDescription() };
return new SelectList(values, "Id", "Name", values.Cast<dynamic>().Where(x => (x.ID == (int)Stage.BLANK)));
}