Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it just me, or is WPF a mess of databinding and custom IValueConverters?

Seriously, it seems like every time I want to make my UI elements talk to each other, I end up coding a new, custom, IValueConverter :(. Someone tell me that I'm doing it wrong, please!

Examples:

  • I wanted a button to be enabled only if my textbox contained a valid URI. Great, time to code up a UriIsValidConverter!
  • Oh oops, I also wanted to disable it while I'm processing something. I guess now I need to code up a UriIsValidAndBoolIsFalseMultiConverter!
  • I want to display a list of files in a certain directory (specified by a textbox) inside a listbox. I guess I need a DirectoryPathToFileList converter!
  • Oh hey, I want icons for each of those files in the listview. Time for a FileInfoToBitmap converter!
  • I want my status to be red if my status-string contains "Error", and green otherwise. Yay, I get to code up a StatusStringToSolidColorBrushConverter!

I'm really thinking this isn't that much better than the old Windows Forms method of just wiring up everything manually using TextChanged events (or whatever). Which I guess is still an option. Is that what people actually do, perhaps, and I'm trying too hard to make everything fit into the databinding paradigm?

So yeah, please tell me if this is really how WPF coding is---or if I'm doing it wrong, and if so, what I should be doing.

like image 263
Domenic Avatar asked Jul 19 '09 15:07

Domenic


People also ask

What is databinding in WPF?

Data binding in Windows Presentation Foundation (WPF) provides a simple and consistent way for apps to present and interact with data. Elements can be bound to data from different kinds of data sources in the form of . NET objects and XML.

How many types of binding are there in WPF?

WPF binding offers four types of Binding. Remember, Binding runs on UI thread unless otherwise you specify it to run otherwise. OneWay: The target property will listen to the source property being changed and will update itself.

What are converters in WPF?

The WPF converters acts as a bridge between the source and the target if the source and target have different data formats or need some conversion. For example, sometimes we need to convert data from one format to another format, when it flows from the source to the target or vice-versa the conversion is required.

What is two way binding WPF?

Two way binding is used when we want to update some controls property when some other related controls property change and when source property change the actual control also updates its property.


3 Answers

Your approach is perfectly valid (though I would use a multibinding for the second example, rather than a such a specialised converter), though by placing all your logic into the XAML you are producing very high coupling between the way the application looks and the way that it behaves, because of this you may want to look into the MVVM pattern to separate those things out.

Under the MVVM pattern your XAML (the view) just contains very simple data bindings into a ViewModel which handles all the logic and updates the view through the INotifyPropertyChanged interface. The code for your third example may look something like:

public class DirectoryManagerViewModel : INotifyPropertyChanged
{
    private string _directory;

    public string Directory
    {
        get { reutrn _directory; }
        set
        {
            if (_directory != value)
            {
                 _directory = value;
                 OnPropertyChanged("Directory");
                 if (IsValidDirectory(value))
                 {
                     PopulateFiles();
                 }
            }
        }
    }

    public ObservableCollection<FileViewModel> Files { get; private set; }

    private bool IsValidDirectory(string directory)
    {
          //return if the directory exists etc.
    }

    private bool PopulateFiles()
    {
         //Populate Files with files in directory
    }
}

Where FileViewModel is another view model which contains the name and the icon for a file.

The advantage of this approach is that the ViewModels can be reused with other views and other technologies such as ASP.NET or Winforms so you are not locked into the WPF stack. (alos if you work in an environment where there are designers responsible for the look and developers responsible for the behaviour, this helps define those boundaries)

At the end of the day though this logic does need to go somewhere and while there are better and worse ways to architect your application you are still going to be writing code that takes a string and converts it into a series of filenames and icons somewhere.

like image 72
Martin Harris Avatar answered Sep 30 '22 05:09

Martin Harris


First, you might want to start by reading about the Model-View-ViewModel pattern (MVVM). Josh Smith had a fantastic article in MSDN Magazine recently. MVVM and WPF go perfectly together. Done right, you won't need IValueConverters so much. The way that you are going about it now is causing a very tight coupling between your visualization and your application actions. MVVM is designed to decouple these elements.

In this context, your view model will track state for you. Your button will be enabled if the CanExecute method on a certain ICommand in your view model returns true. This same concept can handle disabling the button when processing something.

You want to display a list of files in a certain directory that is specified inside a listbox? Have a DirectoryViewModel view model that will handle providing the list of files to the view by binding to the view model. The display of the files can be specified with a DataTemplate specified in XAML with no code behind. This same concept can handle providing the icons to the view whose display can be specified in the template.

You want your status to be red if a status message contains "Error" and green otherwise? Let a view model handle determining the state and let the view bind to that state and now you only need an IStateConverter to convert the state to red or green appropriately (this is one of many ways to handle this problem in the MVVM context).

Get in the habit of keep data and state separate from your view and your applications will be loosely coupled, easier to design and maintain, and easier to test.

like image 22
jason Avatar answered Oct 03 '22 05:10

jason


Don't know if you are wrong, just making it a lot harder than it has to be!

I use MVVM, so where you are writing customer converters, I provide a bindable property on the view model that tells the view what to do. For example:

  1. To display a list of files, I provide a collection that contains that list.
  2. If I want icons the object in that collection has a icon property
  3. If I want a status to be red or green I provide a StatusColorbrush property.

By moving this logic into the view model, I get:

  1. much simpler Xaml.
  2. can test my view logic without the view.

This approach uses one of the strong points of WPF, it's binding capabilities.

like image 34
automatic Avatar answered Oct 01 '22 05:10

automatic