Why Use IEditableCollectionView? - c#

I've got a project I've got to crank out (thanks to an employee quitting on the job before the deadline).
He'd been working in WPF. The interface looked cool, but it never was able to collect data from the company's old data access DLLs. (Rewriting the DLLs is a great idea, but not feasible in the short time left by the deadline) Collecting data was the whole point!
The project was thrown at me, but I'm no WPF developer. I've been told to make it work with WinForms, which is what I know. I had a WinForm interface cranked out in a few hours, and it looks every bit as good as the WPF version ...and I know what it is doing. WPF involves voo-doo I haven't learned yet.
There are things used in the WPF project that I need to get a grasp of what they do, and I do not have time to completely redesign it all.
The Business Logic Layer returns an ObservableCollection to the WPF interface.
The WPF interface takes the ObservableCollection and stores it in a CollectionViewSource using its Source parameter.
OK, I'm immediately thinking DataGridView control and using the DataSource parameter from it.
Am I on track?
What was the point of the IEditableCollectionView? Is it necessary? And if not, should I just remove all references to it?

ObservableCollection, CollectionViewSource etc. are important in the WPF's MVVM (MVC...+) scheme. You could drop them but you could certainly reuse them in a WinForms project. It might actually be better to do so to retain the clean separation between UI and data.
You could also hang on to them and use them as "more standard" collections which would simply result in a little bit of unnecessary overhead. And since meeting your deadline is of utmost importance, this might be the way to go.

The observable collection is used so that other controls can participate when the collection is added to, removed, or refreshed. This helps keep the entire UI in sync. As far as the IEditableCollectionView, it raises the INotifyPropertyChanged event so that the controls on the WPF form automatically update when a property in the collection is updated.
If you are doing this in WinForms, you just need to raise events when your collection has changed.

Related

Monodroid hold / Save dependencies between EditTextFields

I’ve an Interface with many textEdit fields. But any Fields have dependencies to others.
For example:
When textfield_1 is filled, textvield_3 and 4 disabled. But my Layout is Dynamic and I don’t want to Code this dependencies Hard.
Does anyone have an Idea or Solution to Save or hold this dependencies in my Application? And how can I check it.
If I understood your intent correctly I would say the basics would come from ViewModel (as in MVVM design pattern). You could go with the simple INotifyPropertyChanged route or something more "reactive" like RxUI: http://www.reactiveui.net/
All changes happen in the ViewModel (so you can also share it across platforms) and the UI just reacts to changes in the ViewModel data.

Correct application design: data reading and UserControls

this could be a long question, I'll do my best to ask it properly.
I want to read large .txt files with lots of numerical data. In each file there will be "channels" (30-50 channels, with own name, axis units, and of course, data). So I've created a class Channel with that properties, and a class File that has a list of that channels. It also has a method that reads the file and stores everything in lists.
I want to be able to load several files at the same time, and for that I've created a UserControl that consists in a button for loading the file and a ComboBox that displays each channel:
(The ComboBox is bound to an ObservableCollection)
The data is stored in the code behind of the user control. So when I insert in my MainWindow several UserControls I can't access that data.
What I want is have several UserControl...
...and be able to plot the data from each one in that Plotter, and be capable of some control (previous, next..)
My first approach was to store everything in the UserControl, that was easy to do but ineffective.
So what I figured out that might be the solution is to store everything in other place and then access to there from the MainWindow or other place. I've tried VERY HARD to learn MVVM and use it in my project. But I must be very STUPID because I can't get it.
My new approach is described in the next scheme:
My questions:
1.Is this the correct way of doing it? If the MVVM is the way, please, I beg you, please, guide me just a little bit in the beginning, because I am not capable to translate that intricate examples out there of MVVM to my project.
2.If I'm doing it more or less right, how could I store all that data in some other place and the access it from MainWindow? (in my File class I have a method that stores all in lists, so in my UserControl I have the "Browse" button that gets a filename, and then with the read() method I store everything inside (?) the File class, or at least inside the place I've created the new File: the UserControl).
I'll post code, pics, more info, anything if needed. Thanks.
If the MVVM is the way, please, I beg you, please, guide me just a little bit in the beginning, because I am not capable to translate that intricate examples out there of MVVM to my project.
You're already half-way to using something that's MVVM, at least in nature. It isn't "the way", but it would definitely be a (reasonably nice) way to handle this.
In order to design this with an MVVM type of design, you'd want to make your "MY DATA" class be the DataContext of the UserControl. All of the data would be stored there (preferrably in ObservableCollection<T> instead of List<T>, as that will handle binding more effectively).
Your "UserControl1" portion would likely be some form of ItemsControl, bound to a collection of sources. The selected item could then be bound to something on your "MY DATA" class, which determined which "plot" should be displayed.
To answer your questions directly:
1.Is this the correct way of doing it?
This is definitely a step in the right directly. Storing your data separate from your controls is one of the key pillars to making your application more flexible and maintainable (and a large goal of MVVM).
2.If I'm doing it more or less right, how could I store all that data in some other place and the access it from MainWindow?
You handle this by setting the class as the DataContext of your UserControl and/or MainWindow. This allows you to bind to properties on your data class (which is effectively your ViewModel in MVVM terminology).
Also, I know you've tried to study and learn MVVM - and it's difficult to grasp initially, but it is worth the effort. I will say that your design scenario (which is effectively a list of "options" on the left, and a "detail" pane on the right) is not an uncommon one - it's actually similar to my example in my blog series on MVVM, and should be fairly easy to create once you understand the basics.

WPF C# MVC/MVP pattern and user control code-behind

I am developing a large-ish application in WPF/WCF/NHibernate/etc. and have implemented the MVP pattern (although this question is still relevant to MVC) as the core architecture.
It feels quite natural to extend and add functionality as well as to come back and make changes on certain bits and pieces, as far as the core architecture is concerned (controllers, views, etc).
But at times the code-behind-ness of custom user controls that I create feels as if it "breaks" the MVC/MVP paradigm implemented, in that code concerns leak in the design and design concerns leak in the code. Let me clarify again, this is only for user controls. It is my personal opinion that this code-behind model (for both ASP.NET and WPF) is a 'Bad Thing', but no matter what my opinion, I'm stuck with it.
What are your recommendations for best practices in such a scenario? How do you handle such concerns? Do you for instance work around the code-behind-ness of custom controls and if so how??
Since you are using WPF, you should really look into the MVVM (Model-View-ViewModel) pattern. It is a form of the Presentation Model (PM) pattern discussed by Martin Fowler. WPF is very binding-oriented, and provides a very powerful and rich data binding framework for XAML. Using MVVM, you can completely and entirely decouple your ViewModels from your Views, allowing truly POCO UI development that offers the ultimate in separation of concerns and unit testability.
With MVVM, you will be able to modularize and decouple all of your views, including Windows, UserControls, etc., from the code that drives them. You should have no logic in Code Behind other than what is automatically generated for you. Some things are a little tricky at first, but the following links should get you started. The key things to learn are the MVVM pattern itself, Data Binding, Routed Events and Commands, and Attached Behaviors:
MVVM
Data Binding
Attached Behaviors
Attached Commands (VERY USEFUL!)
Routed Commands
Routed Events
WPF + MVVM has a bit of a learning curve up front, but once you get over the initial hurdle, you will never, ever want to look back. The composability, lose coupling, data binding, and raw power of WPF and MVVM are astonishing. You'll have more freedom with your UI than you ever had before, and you will rarely, if ever, have to actually bother with code behind.
I happen to like code-behinds (yet another personal opinion), but they work only as long as they do nothing but facilitate interactions between control events and the rest of the application. I'll admit that I've seen a lot of counter-examples, though. I even wrote a few of them....
Really, all the code-behind should do is "oh, someone clicked this button; there's probably something that wants to know about that." PRISM (from MS patterns and practices) provides a lot of architectural infrastructure for WPF and Silverlight; that includes a publish/subscribe interface that allows the controls and the code-behinds to simply publish an event while not even being aware of possible subscribers, or what the subscribers might do with the event. PRISM also adds commands for Silverlight.
A common variant of MVC for WPF and Silverlight is MVVM (Model, View, ViewModel). The ViewModel makes data available to the user controls in some form that is most useful (such as ObservableCollections, to facilitate two-way binding).
Custom Controls are there to display stuff. In that regard they are no different than a button or a drop down combo box. The trick is that don't let them handle stuff directly. They need to send stuff through the View Interface and the Presenter need to likewise interact with them through the view interface.
Think of it this way. If you ignored MVP the custom control would interact with the model in specific ways. what you doing with MVP is taking those way and defining them with the View Interface. Yes you are adding an extra call layer but the advantage is that you thoroughly document how it interacting with the rest of the system. Plus you get the advantage of being able to rip it out and replace with something entirely different. Because all the new thing needs to do is the implement it's portion of the view interface.
If you have a specific example I can illustrate better.

How should data be synchronized between a WinForms GUI control and the client class?

What method is considered the "standard" for keeping data structures within GUI controls synchronized with the data structures that are maintained by the application?
For example:
In WinForms, if one creates a ListView instance, rather than pointing it to a data structure that represents the items to appear within the list, one must programmatically instantiate ListViewItem(s) and call an .Add method to manually replicate them, one by one, into a data structure that is internal to the ListView itself. This makes sense from a threading standpoint, and it also makes sense within the context of rendering that a control should require a specialized data structure to exist for which the control alone knows the details regarding maintenance.
However, this creates two issues:
Redundancy:
If the client class manages its own list of entities, to allow the user to select among them from the WinForms UI, this entire list must be read, converted and then recreated inside of the UI control via methods such as: .Add(ListViewItem item) Lists now occupy twice as much memory.
Complexity:
Since two lists now exist, one must programmatically ensure that they remain synchronized. This can be achieved with events that are fired from the client class's collection object, or a programmer can simply be careful to always add/remove from one list when they add/remove from the other.
I have seen many instances where programmers will take the shortcut of using a UI element like a ListView as the actual collection object used to maintain the list. For example, each user entered item will be immediately inserted into the ListView, and then when it comes time to access to user's entires, the application just iterates through the ListView. This method fails to apply when you are properly seperating business/application logic from UI logic.
Overall, something just doesn't seem right about storing application data within a data structure that is internal to a GUI control. Likewise, storing two lists and keeping them programmitically synchronized doesn't seem like an elegant solution either. Ideally, one would need only to supply a UI element with a reference to a list that resides within the scope of the client.
So, what is the "right" way to approach this problem?
Every UI control needs some state of its own. With complex controls (like ListView) that state is correspondingly complex. The trick is to make the maintenance of the controls state as simple as possible. With a standard ListView, that's not possible -- the programmer has to do the work.
That's one reason I wrote ObjectListView (an open source wrapper around .NET WinForms ListView). It allows you to use a ListView at a higher level where the maintenance of the controls state is invisible. An ObjectListView operates on your model objects directly:
this.objectListView1.Objects = listOfModelObjects;
this.objectListView1.SelectedObject = aPerson;
Once you can work at this level, data binding itself is no so useful. But, if you really want to use it, you can use the data-bindable DataListView from the ObjectListView project. It gives you the best of both worlds.
With an ObjectListView, there is no reason to switch to the far less interesting DataGridView. An ObjectListView gives you the ease of DataGridView with the nice UI features of a ListView, then plus some more:
Standard DataBinding might make your life a whole lot simpler here. Using a BindingList<T>, you can easily achieve two-way binding. Two-way binding makes it easy to update the UI with changes made programmatically (i.e. by the model) or by the user. The list will remain synchronized.
However, you might want to trade off your ListView for a (readonly) DataGridView if you can afford to. It will make your like a whole lot easier with DataBinding.
dataGridView.DataSource = new BindingList<T>(initialList);
I think there isn't a right approach for this problem. Generally, I'd strongly support separating the data source collection from the UI by all means. Several data binding solutions exists to put the two together.
Anyways, let me make some considerations on the points you exposed.
On Redundancy: You indeed would have 2 lists for the essentially the same entities in the mind of the user. The lists are not at all equivalent.
For a start, there won't be duplication of memory. The list on the UI side may have a reference to the original object in the data source list, but it's nothing more then a reference. The total memory consumption wouldn't be much larger than having a single collection object in the UI
Secondly, the two lists (UI vs. data source) may not have the same number of items. If you use paging in your interface, the UI list may be much smaller than the data source list.
On Complexity: Using a good data binding solution may greatly reduce the complexity of synchronizing UI with its data source. There are some cases where having the two lists separated will actually simplify your code.
Consider the possibility of having a separate window/page/user control/whatever that is responsible for editing (new or old) objects. If you only have a single collection of objects directly on your UI, this separate component would have to reference to the same UI control that holds the list. This simply doesn't makes sense.
DataBinding is the way to go. Take a look at this article, it is very helpful:
Data Binding in .NET / C# Windows Forms
Data binding provides a way for
developers to create a read/write link
between the controls on a form and the
data in their application (their data
model). Classically, data binding was
used within applications to take
advantage of data stored in databases.
Windows Forms data binding allows you
to access data from databases as well
as data in other structures, such as
arrays and collections.
(source: akadia.com)
The problem with accessing the ListView (for example) directly, is that you are modifying the "master" copy of the data in memory. This means that if your user decides to cancel their changes you need to be able roll back any changes they might have made.
So you have the choice, the added memory of two copies of the data structure or the added complexity of having to roll back on cancel.
Check out this article on data binding. For things like ListViews, you can bind to a custom class that implements one of the list interfaces. By adding support to your custom class for events you can automatically update the GUI whenever a change is made to the list (or vice versa).
I just went through this mess with a List(Of MyObject) and the ListView. The ListView is deficient in that it doesn't offer a .DataSource property like many other object containers, such as the ComboBox, ListBox, and DataGridView. I chose to drop the ListView in favor of a DataGridView, simply because I the requirements didn't require a ListView (I added a custom first column to the DataGridView to render an image, which is why I originally chose the ListView. But you are right, the extra code to keep things in synch was too much of a headache. As to your question, do what I did. Figure out if you really require a ListView by considering if you can use a DataGridView instead and meet the requirements.

Strongly Typed Controls in .NET

I am working on a Windows Forms app for quite some time now, and I really find myself doing more typecasts in the GUI code than I ever did in my underlying business code.
What I mean becomes apparent if you watch the ComboBox control that accepts some vague "object" as it's item.
Then you go off and may display some DisplayMember and a ValueMember and so on.
If I want to retrieve that value later I need to typecast my object back to what it was. Like with strings getting the value takes
string value = (string)combobox1.SelectedItem;
Since there are generics in the Framework for quite some time now, I still wonder why in the Hell not one control from the standard toolbox is generic.
I also find myself using the .Tag property on ListViewItems all the time to keep the displayed domain object. But everytime I need to access that object I then need another typecast.
Why cant I just create a ComboBox or ListView with items of type ListViewItem
Am I missing something here or is this just another example of not perfectly well thought through controls?
While the criticism of "didn't use generics" can't be fairly applied to controls developed before their existence... one must wonder about WPF controls (new in .NET 3.0, after generics in .NET 2.0).
I checked out the AddChild method in ComboBox. It takes an object parameter (ugh).
This control is intended to be used primarily via XAML. Was this done this way because there is no way to specify a type parameter in XAML? (aside, is there no way to specify a type parameter in XAML?)
Sorry to have no definitive "Why" answer, just sharing the common misery of needing to cast when working with the UI.
I dont think you're missing anything.
It's just that these classes were created back in the pre-Generics days, and WinForms is simply not cutting edge enough for MS to spend a lot of time changing or extending the API.
I often create wrapper classes for controls. This allows me to use generics. This is often in conjunction with Reflection, which is not type safe at compile time, but can be at run time.
A common source of this problem, I think, is not separating your view/presentation logic from your in-memory data model logic. Which, unfortunately, is an architecture fault that WinForms and the Visual Studio GUI designer are complicit in.
WinForms and the VS designer do not encourage the programmer to separate the management of their data objects from the form classes themselves. It would probably be better if the ComboBox ListViewItem objects didn't offer any support for arbitrary objects, either via generics or Object collections..
Unless you are hacking together something of limited use and lifetime, you should try to avoid storing references to individual data objects right in your controls or forms. They should be managed separately, and if they need to be referenced, it should be done via a model management class designed for the particular type of view class you're working with.
A simple-ish bandage for the problem, though, might be to "map" the text representations that you place into the ComboBox or ListView to the original objects, using a Dictionary field member on your Form class. It's not an ideal solution, but gives you at least a half-step of indirection between your data and your UI controls, which can make your code easier to maintain.
Edit: This is admittedly separate from the ListViewItemCollection class exposing Object instances... The official defense is likely to be that they wanted to support the standard IEnumerable and ICollection interfaces. But there's no reason they couldn't have also provided type-specific overrides of these methods, since it is designed explicitly to store ListViewItem instances. So I have no answer for you on that particular question.
Well, if you data-bind your controls to a DataBindingSource, you can get at your data that way, but AFAIK that's still not strongly typed. If you are displaying multiple parameters/aspects of a single business object, you can bind to that, then access the (strongly typed) members instead -- of course, this all goes back to Turbulent Intellect's answer, which is better separation between model and view. Still, I agree that generic-based typing would help.
It is possible (you can make your own generic controls, if you wish), but the form designer that comes with Visual Studio will freak out if you do this. You'll have to do stuff without it.
You aren't the first one to think of this, and Microsoft has already received a fair share of criticism from the public for this. Let's hope they add support for this in the future.

Categories