Data Window Customization

Jul 18, 2011 at 10:16 PM

Is it possible to replace the default buttons location/aspect?.

For example: I'd like to put them inside a ToolBar, on top of the DataWindow.Add icons, etc.

Or, under Custom mode, provide to my own buttons the OK/Cancel behavior.

I also want to remove the default's DataWindow padding.

Thank you for your support.

Coordinator
Jul 19, 2011 at 6:40 AM

Yes, it's possible. Just pass DataWindowMode.Custom and you can do whatever you want with the datacontext.

Jul 19, 2011 at 1:46 PM

I know that, but, for example, the data window's OK button have a special behavior, it modifies the DialogResult so that it returns true, right?

I want to change this button's position into my toolbar, and customize it...is this possible? or is there an alternative that Catel provides?

I have my own implementation of this, but I want to "play by the Catel's rules" whenever possible.

Thank you.

Coordinator
Jul 19, 2011 at 8:26 PM

Such a thing must be done via the code-behind. Setting the DialogResult is not an MVVM thing, but a UI thing. This is a very hard line to draw for most people, that's why Catel offers out-of-the-box controls that provide such behavior. If you want to implement this yourself, this is what you'll have to do:

  1. Create a custom button
  2. Handle it via a click event (yes, no command, a click event)
  3. In the Click event, cast the current DataContext to a ViewModel and pass the click event forward to the command, and then set the dialogresult in the click handler

It sounds dumb and a bit overcomplex, but this is, IMHO, the best solution possible (and I am pretty sure I thought a lot about it) for MVVM. 

Another example where the layer between View and View Model is when the View does not support binding (such as some Grid controls by 3rd party companies). In that case, you'll have to catch events in the code-behind and then pass them to the view model. This still keeps your viewmodels perfectly testable (no 1 goal of using MVVM), and still provide all functionality required.

I hope you understand what I am saying. If not, just let me know and I will put together an example.

Jul 19, 2011 at 9:01 PM

I understand.Thanks for such a very clear answer.

I have noticed that there is a VM method called SaveAndCloseViewModel

Using this method calls the Save method and closes (or not) according to the Save method's return value the UI (the DataWindow) along with the ViewModel which in my opinions makes sense, but unfortunatelly it returns false from the service that calls the UI. Just without analyzing too much if this is possible or not. It would be very convenient if this could force the service to return "true" instead. What do u think?

 Thanks in advance,and again for your support.

Coordinator
Jul 19, 2011 at 9:05 PM

Can you please explain in detail what you mean? If the Save fails (returns false), the window shouldn't be closed at all. In that case, the Service should not yet return a value. Only if the Dialog is closed (false = cancel, true = saved), the service should return a boolean value.

Jul 19, 2011 at 10:08 PM

When you invoke SaveAndCloseViewModel() (instead SaveModel) the UI is also closed (along with the view model). So, if your View is a modal DataWindow, when you close the associated ViewModel, the Window also gets closed. What I mean is that would be nice that the DialogResult gets the SaveAndCloseViewModel's return value reflected on it. ( I have tested it and when Save returns false, the VM doesn't close.. neither the View, which is very correct.

Am I clear?

Jul 19, 2011 at 11:23 PM

This is basically the idea I suggest (taken from your inicial idea about specializing a Button).I wait for you critics about this.Thank you.

public class SaveViewModelButton: Button

 {public SaveViewModelButton() :

 

{

base()

   Click +=

new System.Windows.RoutedEventHandler(OnClick);

}

 

{

System.Windows.

Window parent = GetParentWindow(this);

 

private void OnClick(object sender, EventArgs e) IViewModel vm = DataContext as IViewModel;

 

bool? bDialogResult = null;

 

// By default (no command bound) we call SaveViewModel() and return true ONLY

 

// if SaveViewModel returns true.

 

if (Command == null)

 {

   

if(vm.SaveViewModel())

      bDialogResult = vm.SaveViewModel();

}

else

{

 

// This is not working propery because the command is invoked twice

 

// Once because of this click and the other through the VM mechanism I think

   Command.Execute(CommandParameter);

   bDialogResult =t

rue;

}

  parent.DialogResult = bDialogResult;

}

 

 

Coordinator
Jul 20, 2011 at 6:13 PM

I see you are getting pretty acquanted with Catel, good job!

 

The only thing I would do different is the double call to SaveViewModel. I would store the result in a boolean and use that to set the DialogResult (otherwise some logic might be handled twice, something some developers are not prepared for). I totally agree that the IUIVisualizerService should only return if succeeded and set the DialogResult, so I am now looking into this.

Jul 20, 2011 at 6:32 PM

Oh sorry.. the double call it's a mistake. Perhaps I was trying to modify something at last time and made that huge mistake.

Another idea that came up it's the following (I hope to be right on this...) Some constructors to DataWindow pass the DefaultButtonMode as a parameter, right?

So.. you can in advance know what kind of behavior the DefaultButton has... for example Ok, or Apply.. (again.. Am I right? .... ) So... if You mark a button with the attribute IsDefault, you know

that button should behave under a certaing mode (OK for example). What if... the DialogResult's value is change according to the DefaultButtonMode enum value?

 

Coordinator
Jul 20, 2011 at 6:50 PM

Stop thinking about all these cool ideas, I can't keep up with implementing them :)

I just implemented the DialogResult for views closed from within the viewmodel (now checking in). Please create a new issue for the other idea, then I will try to make it for 2.0 (otherwise it will be 2.1), but implemented it will be for sure!

Jul 20, 2011 at 7:14 PM

Thank you for your support and consideration.

I will stop on this topic :) but I'm sure another questions will be coming :).

 

Coordinator
Jul 20, 2011 at 7:16 PM
Edited Jul 20, 2011 at 7:16 PM

No, don't stop, it was sarcasm :) Keep all the good ideas coming, what's not implemented in the next version will be implemented in version++!

Keep all the ideas coming, we're currently working very hard towards 2.0 (I hope I can commit 2 new features this evening), so it's possible that not all feature requests can be implemented for 2.0.