I'm just starting out in WPF and I'm building a simple movie library as a test project to help me find my feet.
I'm storing my movie information in XML, for example:
<movie id="1" title="Back To The Future" date="1985" ... />
The movies appear in a list and when clicked the fields will become editable. I've got that working by using two Data Templates to style the list items, applied via a Trigger on the ListBoxItem.IsSelected property.
But for binding and editing the data, I'd be really grateful for some advice. I've tried each of the approaches below with varying degrees of success. Which do you think makes the most sense? Are there any other things I could try?
Approach 1: Bind to XML directly using XMLDataProvider in XAML. In this case the ListBox binds to the XmlDataProvider and the individual control elements are bound via XPath expressions. It's very simple to get started, but this approach seems to become tricky when editing the data. We need rather a lot of ValueConverters just to ensure that the data is presented sensibly and saved back to the XML file in the appropriate format.
Approach 2: Create a custom Movie class that receives the XML and exposes all the movie attributes as public properties to which the controls are bound. This feels more robust and flexible, but seems to require a lot more work to implement. Every property needs to be explicitly exposed in code and validation is a pain.
Approach 3: A bit like approach 2 but with a Movie user control instead of the ListBox + Data Templates. I started with this and quickly abandoned it because I couldn't see any advantages over approach 2.
I realise it's not a straightforward question and that there are a lot of factors to consider, but any thoughts on the various pros/cons (or whether there are any tricks I'm missing) would be appreciated. Please let me know if you would like more info or code samples. And apologies if this question is inappropriate or unwelcome.
Many thanks.
If its just for displaying, whether or not you use templates, approach one is more efficient as the wpf engine works directly with the xml.
If your going to do editing operations on the data, it is best to go with Approach two as you have the flexibility to manipulate the data far better. Using a class you can do the exact same thing as in approach one with binding as the engine will read from the objects just like the xml file. This approach allows for easily binding the elements 2 way and if its from an IObservable Collection, you can ovveride the method that is called when the data is changed, so it updates the xml.
Related
I'm struggling with this issue. I have a webservice that retrieves all the possible labels (with keys) for my application. This labels may vary from culture to culture (en, fr, de, pt, etc).
My doubt is how can I create/fill a resource file for that culture and fill with those labels/keys?
Those labels are managed by a backend server, and I have a GET to a REST webservice to get those strings.
Thanks
I don't think that there are any best practices for this. You need to write a mini-framework that could do one of the things listed bellow:
[If using MVVM] You could put the labels on your view model and bind to them in XAML. Involves writing lots of properties even when using snippets. Also, lots of properties are a pain when binding.
[If using MVVM] A better design similar to 1 where you store the labels in a separate class which is a property in your view model. Let your imagination go wild, use singleton, caching, etc. This is the most dangerous approach.
You could create one (or more classes) like any view model (at least with INotifyPropertyChanged), store it as a XAML resource and bind to it, populate it when you want. More XAML when binding labels but does what you're asking for and it's easily readable for others.
In all the options listed above you can change locale at runtime with translation being effective immediately (assuming you implemented INotifyPropertyChanged and bound label to take account of this), which you don't get with .resx and changing thread culture.
I would try all 3 as sample projects and see which would make a time-efficient way of manipulating label resources (adding, removing, changing, renaming them, and of course maintaining their contents).
Personally, I would go with 3. I listed the others just to be a little exhaustive.
Please bear with me for the length of this question, I tried to be as descriptive as possible. I am new to WPF programming. I am basically trying to build the RadDataFilter control:
RadDataFilter is used to filter collection by building query expression. The control is generally used by bringing all data from the database and then filtering on them.
However, I am trying to use it to build SQL query expression and then I query the database to retrieve the data. Our company has license for Telerik products so I had to try and use the control. Unfortunately, the control is not flexible to the extent that I would want to customize the Left Dropdown (RadComboBox).
As we have several items which users can filter on, it is not feasible to provide them with a single dropdpwn. I would like to have a custom control instead of the dropdown.
I have the following workaround to this problem:
Extract the Template for that control and override it in my XAML as described here. However, inspite of doing this, I am unable to change the control. I assume it is due to my inadequate knowledge in WPF.
Try to change the Source code for Telerik (We have the license for the code too). However with this approach, we need to keep making changes with every upgrade, which is high maintenance for the team.
Try to build a custom control.
I am looking for the 3rd approach. If there is an easy way (using the first 2 approaches) or any other solution to achieve this, please let me know and I shall try that.
To implement the 3rd approach, I am thinking to use a TreeView with each node using a ControlTemplate (containing my Custom Control). I will override the ToString() method of the Custom Control that gives me the one query condition. Once done, I would iterate through the children of the root node to build the final query expression.
However as I notice, we need 2 different ControlTemplates (one which allows creating a filter expression and the other with the operator, similar to RadDataFilter). I do not know how to set multiple templates like this.
This may sound simple to some of the developers out there, but I am really new to C# and WPF programming and would need time and experience to be comfortable with it.
Please let me know if you know any other solution that I can try to solve this problem. If you feel it is better to create a custom control, please guide me on whats the best way to implement this. Also comment on my approach to create the custom control.
Thanks!
I resolved it. Took the first approach:
"Extract the Template for that control and override it in my XAML as described here.."
I'm writing an admin form for some fairly complex objects. Its a standard repeater which displays some 'basic' information (name, id etc.) for each object row.
Clicking 'Edit' for a row expands it (using JQuery) to reveal the full horror of all the associated editable objects. One of these is a list of documents associated with each row and needs to be JQuery-editable so the user could click 'edit' to open up the full row gui, then un/select checkboxes to de/associate documents and then hit 'Save' to persist everything.
Currently I'm using nested repeaters to store the initially-hidden fields - the repeater generates a hidden formfield containing a comma-separated list of IDs for the assoc documents. When it comes to populating the Edit gui I do a split operation on the delimited string and set/unset the checkboxes as required.
This is proving a nightmare from a maintainability perspective and in my frustrated wanderings of the web in search of a solution i noticed JQuery has some functionality to act as a client-side database. Does any one have any experience of this, and if so, would you recommend it? My custom JS to parse csv-strings and dynamically build the gui is starting to grind me down a bit.
Thanks in advance,
5arx
Your getting into the realm of very advanced client-side behavior, and are bumping into a phenomenon that I think a lot of Web Forms developers hit. Trying to mash two paradigms into each other.
Without going into a lot of detail, my advice would be to go with a "Pure AJAX" approach to solving your client woes. The basic outline is this:
Use AJAX calls to grab a JSON representation of your data structure
In your case... jQuery.ajax jQuery.get jQuery.getJSON
Use a client side templating / binding framework to generate the UI and bind the JSON objects to those elements. There are a couple of good options here.
jQuery
Templating: http://api.jquery.com/category/plugins/templates/
Data Binding: http://api.jquery.com/category/plugins/data-link/
Knockout JS
Knockout can use jQuery templating, but implements it's own version of databinding.
Make actions on the UI call web service methods to handle data manipulation operations.
You can implement the JSON stuff however you feel best suits your needs, but in ASP.Net you basically have two options:
WCF
Page Methods
It's probably going to involve some re-architecting on your part, but if you want to achieve really nice client-side behavior you are going to have to bite the bullet and just do it.
This guide on optimizing DataBinding says:
There is a significant performance impact when you data bind to a single CLR object with thousands of properties. You can minimize this impact by dividing the single object into multiple CLR objects with fewer properties.
What does this mean? I am still trying to get familiar with DataBinding, but my analogy here is that properties are like SQL table fields, and objects are rows. This advice then translates to "to avoid problems with a large number of fields, use less fields and create more rows". As this doesn't make any sense to me, possibly my understanding of databinding is completely askew?
Does this advice actually apply? I am unsure if it is specific to .NET 4/WPF, while i am using 3.5 and a custom WinForms based control library (DevExpress)
As an aside: am I correct in thinking DataBinding uses reflection when an using IList style datasource?
This is not just a academic question. I am currently trying to speed up loading a XtraGridView (DevExpress Control) with ~100,000 objects with 50 properties or so.
This advice then translates to "to avoid problems with a large number of fields, use less fields and create more rows"
I think it should translate to "use less fields and create smaller tables" (i.e. with less fields). And the original advice should read "[...]dividing the single class into multiple classes", with fewer properties. As you correctly noted, it wouldn't make sense to create more "rows"...
Anyway, if you do have a class that exposes hundreds or thousands of properties, you have a far more serious problem than binding performance... This is a serious design flaw that you should fix after reading some OO principles.
Does this advice actually apply? I am unsure if it is specific to .NET 4/WPF, while i am using 3.5 and a custom WinForms based control library (DevExpress)
Well, the page you mentioned is about WPF, but I think the idea of binding to smaller objects can apply to WinForms too (because the more properties need to be watched, the slower it will be)
As an aside: am I correct in thinking DataBinding uses reflection when an using IList style datasource?
You're partially correct... it actually uses TypeDescriptor, which in turns uses reflection to examine regular CLR objects. But this mechanism is much more flexible than reflection: a type can implement ICustomTypeDescriptor to provide its own description, list of members, etc (DataTable is one example of such a type)
You are solving the wrong problem. It will take a typical user well over a week to find back what she is looking for when she's got 5 million fields to search through. The speed of your UI becomes irrelevant. Only a machine can do a better job finding the data back.
You've got one. Help the user narrow down what she is searching for by letting her enter search terms so that the total query result doesn't contain more than, say, a hundred rows. The dbase engine helps you make that fast. And it automatically solves your grid perf problem.
I'm designing a car catalogue and need to use XML files for storage. In previous projecs, I was manually editing XML files with Linq. However, I came across XML serialization and am thinking this might be a better approach. Each item in the catalogue would be of type CarItem and contain various attributes. The catalogue can contain a few hundred cars and I'm worried about performance. If I deserialize the XML file, will all the CarItems be instantiated straight away? Is there a way for me to be able to choose which object gets deserialized based on parameters? For example, I'd like to say "if car color attribute is red, then only deserialize red CarItems into objects".
Thanks for any suggestions
There's quite a few posts with good examples of how you can control what you pull out and instantiate into objects/scalars using XDocument.
Shawn Oster's post in this thread I believe is quite close to what you want using linq. You can add where clauses to suit your requirements easily.
Yes, they all will be instantiated. However, few hundred objects is not a big deal for a class with some simple fields. Give it a try and check performance.