Friday, 20 February 2009

WPF transparent windows and VNC

 
We've found that VNC doesn't transmit any info for transparent windows in a WPF app..
So.. when we use VNC for support.. we can't see :
 
The logon box
The popup menus
Any MessageBoxes
 
Not handy…. (not sure of the solution to this yet – might be something we can do with VNC.. might be a "support skin" change.

Thursday, 12 February 2009

Monday, 2 February 2009

Passing an Enum as a CommandParameter

We wanted to pass an Enum as a CommandParameter and struggled to find the right syntax. The final result turned out to be straightforward.
xmlns:Util="clr-namespace:Sandstorm.Documents.FlexBlockBookings.Util


<RadioButton Name="rbPriceByActivity"
Content="By Activity"
Command="{Binding Path=BBChangePricingCommand}"
CommandParameter="{x:static Util:PricingOptions.ByActivity}"/>

Sunday, 1 February 2009

Validation in MVVM

We're following the MVVM pattern and using Josh Smith's example app Using a Viewmodel to provide meaningful Validation Error Messages to implement validation.

When I was in debugger I noticed that some code was executing twice so I traced through the code once the focus left the textbox.

The order of processing was:
[External Code]
ViewModel.Property.Set
OnPropertyChanged
[External Code]
ViewModel.this[propertyName]
But when you add in a FormattingConverter the order becomes:
[External Code]
FormattingConverter.ConvertBack
[External Code]
ViewModel.Property.Set
OnPropertyChanged
[External Code]
ViewModel.Property.Get
[External Code]
FormattingConverter.Convert
[External Code]
ViewModel.this[propertyName]
[External Code]
ViewModel.this[propertyName]
Which means that the validation gets fired twice.

Because we don't want invalid data in our Model we've recently moved the setting of the Model.Property into the ModelView.this[propertyName] method - not ideal but it is the last opportunity where we still have control. Of course the "double-validation" results in the Model.Property being set twice. Not usually a problem but I fear some hidden side-effect somewhere down the line.

Another slight aggravation is that the Convert function is called before the validation and therefore invalid data will fail to convert then we'll attempt the conversion in the validation process (which was the whole point of this exercise).

IsVisibleChanged

I have the following code which is trying to detect that I’ve clicked on a button and my UserControl is now visible, so I want to set focus to a sensible control in that usercontrol.

void UCBBNotes_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
  if ((bool)e.NewValue == true)
  {
     bool a = txtNotes.Focus();
     // a returns false 
     txtNotes.UpdateLayout();
     bool b = txtNotes.Focus();
     // b returns true
  }
}

So, when reacting to certain events such as “IsVisibleChanged”, the event is called before the layout has updated all the child controls. So txtNotes.Focus() fails because txtNotes.IsVisible = False at that point.

This can either be fixed as above by forcing an UpdateLayout by the Dispatcher – which probably isn’t ideal. Or, instead of watching for the usercontrol to become visible, watch for the textbox we want to focus upon to become visible, like this :

void txtNotes_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
  if ((bool)e.NewValue == true)
  {
     txtNotes.Focus();
  }
}