For some unknown reason people use Regex.
This is a useful link with examples from O'Reilly: Regex 101
Thursday, 16 April 2009
Monday, 6 April 2009
Constructors
It became apparent the other day that I'd either forgotten some stuff about constructors or never knew it in the first place.
This web page has a good explanation of all the issues: Constructors
For example, what I hadn't really considered is that:
is converted by the compiler into:
Similarly 'this' can be used to invoke constructors in the same class:
This web page has a good explanation of all the issues: Constructors
For example, what I hadn't really considered is that:
public class MySimpleClass
{
public MySimpleClass()
{
}
}is converted by the compiler into:
public class MySimpleClass
{
public MySimpleClass() : base()
{
}
}which makes a bunch of stuff easier to understand.Similarly 'this' can be used to invoke constructors in the same class:
public class MySimpleClass : MyBaseClass
{
public MySimpleClass() : this(5)
{
}
public MySimpleClass(int x) : base(x)
{
}
}
DataTemplateSelector
On our till roll I want to display each different category of product using a specific DataTemplate.
We start by defining the DataTemplates to be used in the usual way:
Then the DataTemplateSelector which is the link between the xaml DataTemplates and the C# class (TillRollTemplateSelector) that determines which template to use:
Then we need to wire up the template selector resource (tillTemplateSelector) to the ListBox that will display the data:
Finally, we define the C# class:
The object item passed to the SelectTemplate method is of the same type as bound to the ListBox via the ItemsSource.
We start by defining the DataTemplates to be used in the usual way:
<DataTemplate x:Key="listBookingTemplate">...
<DataTemplate x:Key="listCCardTemplate">...
<DataTemplate x:Key="listCashTemplate">...
<DataTemplate x:Key="listDefaultTemplate">...
Then the DataTemplateSelector which is the link between the xaml DataTemplates and the C# class (TillRollTemplateSelector) that determines which template to use:
<ss:TillRollTemplateSelector
BookingTemplate="{StaticResource listBookingTemplate}"
CCardTemplate="{StaticResource listCCardTemplate}"
CashTemplate="{StaticResource listCashTemplate}"
DefaultTemplate="{StaticResource listDefaultTemplate}"
x:Key="tillTemplateSelector" />
Then we need to wire up the template selector resource (tillTemplateSelector) to the ListBox that will display the data:
<ListBox Name="theTillRoll" Height="250" Width="330"
ItemsSource="{Binding Source={StaticResource ViewModel}, Path=SaleItems}"
ItemTemplateSelector="{StaticResource tillTemplateSelector}"
/>Finally, we define the C# class:
public class TillRollTemplateSelector : DataTemplateSelector
{public DataTemplate BookingTemplate { get; set; }
public DataTemplate CashTemplate { get; set; }
public DataTemplate CCardTemplate { get; set; }
public DataTemplate DefaultTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{if (item is BookingLineItem) return BookingTemplate;
if (item is CashPaymentLineItem) return CashTemplate;
if (item is CCardPaymentLineItem) return CCardTemplate;
return DefaultTemplate;}
}
The object item passed to the SelectTemplate method is of the same type as bound to the ListBox via the ItemsSource.
MultiBinding
I wanted to control the IsEnabled property of a Button based on the properties of two other controls.
Specifically I wanted to only enable the LogIn button if both the Site combobox and UserName textbox had a value available.
I created a MultiBinding for the Button like this:
And a IMultiValueConverter like this:
The array of object[] values are presented in the same order as the Bindings within the MultiBinding.
Specifically I wanted to only enable the LogIn button if both the Site combobox and UserName textbox had a value available.
I created a MultiBinding for the Button like this:
<Button.IsEnabled>
<MultiBinding Converter="{StaticResource loginConverter}">
<Binding ElementName="xSite" Path="SelectedIndex"/>
<Binding ElementName="xUsername" Path="Text"/>
</MultiBinding>
</Button.IsEnabled>
And a IMultiValueConverter like this:
public class LoginConverter : IMultiValueConverter
{public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{ // SelectedIndex of the ComboBoxint selectedIndex = (int)values[0];
// Length of Text in TextBoxint selectedLength = ((string)values[1]).Length;
// Only enable Button if both Combo and TextBox have data if (selectedIndex == -1 || selectedLength==0) {return false;
}
else {return true;
}
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{throw new NotImplementedException();
}
}
The array of object[] values are presented in the same order as the Bindings within the MultiBinding.
Friday, 13 March 2009
Forcing OnPropertyChanged to update the UI
Having used my new Func<T, T> friend (see Action<T> and Func<T, TResult>) the bound TextBox refused to show the revised value. Even though OnPropertyChanged("...") had been called the property's "getter" was not called by WPF.
I don't really understand why.
To get round this problem I added a FormattingConverter to the TextBox called DoNothingConverter. Its presence is sufficient to ensure the UI updates.
I don't really understand why.
To get round this problem I added a FormattingConverter to the TextBox called DoNothingConverter. Its presence is sufficient to ensure the UI updates.
public class DoNothingConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
}
Labels:
Converters,
Data Binding,
Formatting,
Validation,
WPF
Action<T> and Func<T, TResult>
I wanted to pass a validation routine to my SetValue method that uses generics. So I used the Action delegate system.
delegate system instead. Since I want the result to be of the same type as the passed argument I used <T, T> instead of <T, TResult>.
protected void SetValue(T newValue, Action validate)
{
...
validate.Invoke(newValue);
...
} That worked fine until I wanted to change the value (for formatting purposes). So I moved to using the Func
protected T SetValue(T newValue, Func validate)
{
...
newValue = validate.Invoke(newValue);
...
}
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.
Subscribe to:
Posts (Atom)