Displaying a formatted 'DateTime' in a WPF 'TextBlock' - c#

In my WPF application, I have a static List<Guest>. Guest has properties like Name, Lastname, Birthday, etc.
My question concerns Birthday. I would like to display Birthday, which is of type DateTime, in a TextBlock. The output format that I want is something like DD/MM/YYYY. I've thought of using a parsing approach like this:
DateTime.ParseExact(s, "yyyyMMdd").ToLocalTime()
Is there a better way to go that avoids this kind of parsing? For instance, does C# have a converter for DateTime? Note that I need to do this conversion only for output.

The painful way is to make it manually with formatting and parsing. The elegant way is to bind your form to an object containing your properties. When using object-data binding you can specify formats. The conversions in both ways are carried out automatically.
Besides the advantage of having an automatic conversion to and from strings, you have the advantage that you can separate the business logic from your form. You can apply any logic to a property called guest.DateOfBirth (or just DateOfBirth if the logic is inside the Guest class), for instance, instead of applying it to a construct like DateTime.Parse(textBox13.Text), which makes it a lot easier to understand and maintain the code.
See:
Data Binding for Windows Forms (on developerfusion)
Data binding concepts in .NET windows forms (on CodeProject)

Related

Perform conversions on all datetimes on get/set?

I have a database first ASP.NET MVC (C#) project with EF6, which uses a lot of DateTime objects.
They are stored in the database as my local Time-Zone(TZ), however some users are in different TZs (also stored in the database) and I would like to present them with DateTimes for their own TZ.
I have set up some functions accessible from all relevant controllers to do the conversions, but I'm hoping there is a quicker way to apply them in all cases than finding and explicitly converting each instance of each DateTime where needed to display on every view and converting them back again after form POSTs.
On loading a view, the TZ needs to be converted to the User's TZ.
On saving a form, any DateTimes in the form need to be converted back again.
The functions which perform the conversions first check whether it is required according to the User's recorded TZ.
Is there some way I can put all DateTime objects through the conversion when getting and setting them, or something along those lines?
This largely depends on how you access your database. Let's take the Entity Framework example
There, you have the Value Converters
Value converters allow property values to be converted when reading from or writing to the database. This conversion can be from one value to another of the same type (for example, encrypting strings) or from a value of one type to a value of another type (for example, converting enum values to and from strings in the database.)
So in this example, you would create your own DBContext with the TZ in the constructor and pass it to the converter
var converter = new LocalToTZConverter<DateTime>(timezone);
modelBuilder
.Entity<DateEnabled>()
.Property(e => e.Created)
.HasConversion(converter);
Assuming that you use some kind of ORM, pretty much everyone has it's own conversion. If this is something you implement yourself, then you'd handle it in your repositories and have it as a coding practice to never access data directly (only though the repos).

Custom JSON converter for Noda Time

I'm developing for .NET Core, so I'm using the unstable latest alpha of Noda Time (2.0.0-alpha20160729). Data is being handled with JSON.
I will be accepting user input for a date of birth field, and I want to support multiple input formats in case the user can't follow directions gets confused. For example, I want to accept both MM-dd-yyyy and M/d/yy, among others.
The serialization docs specifically state the following:
Custom converters can be created easily from patterns using NodaPatternConverter.
I cannot for the life of me figure out how to do this though. From what I understand, I will need to implement both NodaPatternConverter<LocalDate> itself, IPattern<LocalDate> for parsing, and Action<T> for validation.
I started writing IPattern.Parse<LocalDate>, but that function returns ParseResult<LocalDate> which is apparently inaccessible. It cannot be instantiated or used in any way that I have found. I'm therefore stuck.
How do I properly create a custom JSON converter for Noda Time?
Firstly, this doesn't sound like the right thing to do in a JSON converter. If you're accepting user input directly in your JSON, that should be treated as a string, and parsed later, IMO. JSON is a machine-to-machine format, not a human-to-machine format. Assuming this is a web app, you might want to use moment.js to parse the data at the client and reformat it as ISO-8601. Alternatively, deserialize it as a string and then convert it in your server-side code.
Anyway, for a JSON converter you only need to implement IPattern<LocalDate> - you don't need to implement NodaPatternConverter<LocalDate> as that already exists. You just need:
var pattern = ...;
var converter = new NodaPatternConverter<LocalDate>(pattern);
Now, to implement your pattern, you probably want to actually create it out of existing patterns - write an implementation which delegates to one IPattern<LocalDate> after another until the result is a ParseResult<T> which is successful - or return the final unsuccessful ParseResult<T>. Note that ParseResult<T> isn't inaccessible - but you can't (currently) create your own instance of it. That's something I should probably address, but in this case you don't really need to.
The code you need already exists but isn't exposed - you want the Parse part of CompositePattern. To implement the Format part, you could just use the first of your patterns to format the value... if you even need to.

Override DateTime serialization to string

In my WPF app, I want to give the user the option to present all the dates in different time zones. That is, to keep the data as is but only present it differently in TextBlock Text Binding to DateTime.
I'm trying to achieve this without introducing a wrapping type or else use converters - this would be bad design as this could easily be missed by other developers who would be working on the code. Also, that way the existing code could be kept intact.
Is there a way to intervene in the DateTime serialization to string inside the TextBlock binding and insert my own logic there? using a custom serializer?
Or otherwise, is there a way for me to override the basic DateTime.ToString() Method and insert my own logic there?
you can use converter in binding:
https://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter(v=vs.110).aspx
IValueConverter
xaml:
“Source =”{Binding MyDate, Converter={StaticResource MyDateTimeZoneConverter}}
and add Timezoneconversion logic into class MyDateTimeZoneConverter:IValueConverter{...}

Dynamic form with no real OOP or objects?

I am tacking a large refactor of a project, and I had asked this question to confirm/understand the direction I should go in and I think I got the answer that I wanted, which is not to throw away years worth of code. So, now begins the challenge of refactoring the code. I've been reading Martine Fowler and Martin Feathers' books, and they have a lot of insight, but I am looking for advice on the ultimate goal of where I want the application to be.
So to reiterate the application a little bit, its a dynamic forms system, with lots of validation logic and data logic between the fields. The main record that gets inserted is the set of form fields that is on the page. Another part of it is 'Actions' that you can do for a person. These 'Actions' can differ client by client, and there are hundreds of 'Actions'. There is also talk that we can somehow make an engine that can eventually take on other similar areas, where a 'person' can be something else (such as student, or employee). So I want to build something very de-coupled. We have one codebase, but different DBs for different clients. The set of form fields on the page are dynamic, but the DB is not - it is translated into the specific DB table via stored procs. So, the generic set of fields are sent to the stored proc and the stored proc then decides what to do with the fields (figure out which table it needs to go to). These tables in fact are pretty static, meaning that they are not really dynamic, and there is a certain structure to it.
What I'm struggling specifically is how to setup a good way to do the dynamic form control page. It seems majority of the logic will be in code on the UI/aspx.cs page, because its loading controls onto the webpage. Is there some way I can do this, so it is done in a streamlined fashion, so the aspx.cs page isn't 5000 lines long? I have a 'FORM' object, and one of the properties is its' 'FIELDS'. So this object is loaded up in the business layer and the Data layer, but now on the fron end, it has to loop through the FIELDS and output the controls onto the page. Also, someway to be able to control the placement would be useful, too - not sure how do get that into this model....
Also, from another point of view - how can I 'really' get this into an object-oriented-structure? Because technically, they can create forms of anything. And those form fields can represent any object. So, for example, today they can create a set of form fields, that represent a 'person' - tomorrow they can create a set of form fields that represent a 'furniture'. How can I possibly translate this to to a person or a furniture object (or should I even be trying to?). And I don't really have controls over the form fields, because they can create whatever....
Any thought process would be really helpful - thanks!
How can I possibly translate this to to a person or a furniture object
(or should I even be trying to?)
If I understand you correctly, you probably shouldn't try to convert these fields to specific objects since the nature of your application is so dynamic. If the stored procedures are capable of figuring out which combination of fields belongs to which tables, then great.
If you can change the DB schema, I would suggest coming up with something much more dynamic. Rather than have a single table for each type of dynamic object, I would create the following schema:
Object {
ID
Name
... (clientID, etc.) ...
}
Property {
ID
ObjectID
Name
DBType (int, string, object-id, etc.)
FormType ( textbox, checkbox, etc.)
[FormValidationRegex] <== optional, could be used by field controls
Value
}
If you can't change the database schema, you can still apply the following to the old system using the stored procedures and fixed tables:
Then when you read in a specific object from the database, you can loop through each of the properties and get the form type and simple add the appropriate generic form type to the page:
foreach(Property p in Object.Properties)
{
switch(p.FormType)
{
case FormType.CheckBox:
PageForm.AddField(new CheckboxFormField(p.Name, p.Value));
break;
case FormType.Email:
PageForm.AddField(new EmailFormField(p.Name, p.Value));
break;
case FormType.etc:
...
break;
}
}
Of course, I threw in a PageForm object, as well as CheckboxFormField and EmailFormField objects. The PageForm object could simply be a placeholder, and the CheckboxFormField and EmailFormField could be UserControls or ServerControls.
I would not recommend trying to control placement. Just list off each field one by one vertically. This is becoming more and more popular anyway, even with static forms who's layout can be controlled completely. Most signup forms, for example, follow this convention.
I hope that helps. If I understood your question wrong, or if you'd like further explanations, let me know.
Not sure I understand the question. But there's two toolboxes suitable for writing generic code. It's generics, and it's reflection - typically in combination.
I don't think I really understand what you're trying to do, but a method using relfection to identify all the properties of an object might look like this:
using System.Reflection;
(...)
public void VisitProperties(object subject)
{
Type subjectType = subject.GetType();
foreach (PropertyInfo info in subjectType.GetProperties()
{
object value = info.GetValue(subject, null);
Console.WriteLine("The name of the property is " + info.Name);
Console.WriteLine("The value is " + value.ToString());
}
}
You can also check out an entry on my blog where I discuss using attributes on objects in conjunction with reflection. It's actually discussing how this can be utilized to write generic UI. Not exactly what you want, but at least the same principles could be used.
http://codepatrol.wordpress.com/2011/08/19/129/
This means that you could create your own custom attributes, or use those that already exists within the .NET framework already, to describe your types. Attributes to specify rules for validation, field label, even field placement could be used.
public class Person
{
[FieldLabel("First name")]
[ValidationRules(Rules.NotEmpty | Rules.OnlyCharacters)]
[FormColumn(1)]
[FormRow(1)]
public string FirstName{get;set;}
[FieldLabel("Last name")]
[ValidationRules(Rules.NotEmpty | Rules.OnlyCharacters)]
[FormColumn(2)]
[FormRow(1)]
public string LastName{get;set;}
}
Then you'd use the method described in my blog to identify these attributes and take the apropriate action - e.g. placing them in the proper row, giving the correct label, and so forth. I won't propose how to solve these things, but at least reflection is a great and simple tool to get descriptive information about an unknown type.
I found xml invaluable for this same situation. You can build an object graph in your code to represent the form easily enough. This object graph can again be loaded/saved from a db easily.
You can turn your object graph into xml & use xslt to generate the html for display. You now also have the benefit of customising this transform for differnetn clients/versions/etc. I also store the xml in the database for performance & to give me a publish function.
You need some specific code to deal with the incoming data, as you're going to be accessing the raw request post. You need to validate the incoming data against what you think you was shown. That stops people spoofing/meddling with your forms.
I hope that all makes sense.

Building a string representation of an object using a "mask" or user supplied Format String

I'm not really sure what tags should be on this sort of question so feel free to give me some suggestions if you think some others are more suited.
I have a dynamic object with an unknown number or properties on it, it's from a sort of dynamic self describing data model that lets the user build the data model at runtime. However because all of the fields holding relevant information to the user are in dynamic properties, it's difficult to determine what should be the human readable identifier, so it's left up to the administrator. (Don't think it matters but this is an ASP.NET MVC3 Application). To help during debugging I had started decorating some classes with DebuggerDisplayAttribute to make it easier to debug. This allow me to do things like
[DebuggerDisplay(#"\{Description = {Description}}")]
public class Group
to get a better picture of what a specific instance of an object is. And this sort of setup would be perfect but I can't seem to find the implementation of this flexibility. This is especially useful on my dynamic objects because the string value of the DebuggerDisplayAttribute is resolved by the .NET framework and I have implementations of TryGetMember on my base object class to handle the dynamic aspect. But this only makes it easier for development. So I've added a field on what part of my object is still strongly typed and called it Title, and I'd like to let the administer set the implementation using their own format, so to speak. So for example they might build out a very simplistic rental tracking system to show rentals and they might specify a format string along the lines of
"{MovieTitle} (Due: {DueDate})"
I would like that when they save the record to add some logic to first update the Title property by resolving the format string to substitute each place holder with the value of the appropriate property on the dynamic object. So this might resolve to a title of
"Inception (Due: May 21, 2011)", or a more realistic scenario of a format string of
"{LastName}, {FirstName}"
I don't want the user to have to update the title of a record when they change the first name field or the last name field. I fully realize this will likely use reflection but I'm hoping some one out there can give me some pointers or even a working example to handle complex format strings that could be a mix if literal text and placeholders.
I've not had much luck looking for an implementation on the net that will do what I want since I'm not really sure what keywords would give me the most relevant search results?
You need two things:
1) A syntax for formatting strings
You have already described a syntax where variables are surrounded by bracers, and if you want to use that you need to build a parser that can parse that. Perhaps you also want to add ways to specify say a date or a number format.
2) Rules for resolving variables
If there is a single context object you can use reflection and match variable names to properties but if your object model is more complex you can add conventions for searching say a hierarchy of objects.
If you are planning to base your model objects on dynamic chances are that you will find the Clay library on CodePlex interesting.

Categories