Category Archives: XAML

Toggling visibility On Mouse Over

This is something I consider a good find because there is no logical explanation why it behaves as follows but the fact that it does, demands a blog post:

I had a stack panel with one text box and one button. This stack panel was part of my listbox item template hence repeated for each list item. I wanted to toggle the visibility of the button in my stack panel based on the mouse over status of the list item. So basically, when your roll your mouse over the listitem, i want that button to show up. I put the standard xaml as follows:

<StackPanel >
<TextBlock Text=”{Binding Path=Name}” />
<Button 
Visibility=”{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type StackPanel}} , Path=IsMouseOver, Converter={StaticResource BooleanToVisibilityConverter}}”/>
</StackPanel>

And guess what, the toggling was not working property! The button would show up when i roll mouse on the left side of stack panel but as soon as it comes near the button, the button would disappear. It looked really fiddly and funny since the button kept blinking randomly. There could be a logical explanation for this but in any case it was not how its supposed to behave because the button is inside the stack panel and as long as i have set an event on the mouse over of stackpanel, the button should respect that.

After some research, i discovered that if the background of the stack panel was set to a colour then this fiddly behaviour of the button would stop and the button would stay visible as long as i have mouse on any area of the entire Stackpanel. So finally i had to put a transparent background to the panel to make this thing work correctly.

<StackPanel Background=”Transparent”>
<TextBlock Text=”{Binding Path=Name}” />
<Button 
Visibility=”{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type StackPanel}} , Path=IsMouseOver, Converter={StaticResource BooleanToVisibilityConverter}}”/>
</StackPanel>

Advertisements

String.Format options

No formatting

<TextBlock Grid.Row="1">No Formatting</TextBlock>
<TextBlock Grid.Row="1" Grid.Column="1"
 Text="{Binding ElementName=MyValue,Path=Value}"/>

Result:  No formatting 6.254789965422

 

Applying a Standard Format Specifier

<TextBlock Grid.Row="2">Currency</TextBlock>
<TextBlock Grid.Row="2" Grid.Column="1"
           Text="{Binding ElementName=MyValue,Path=Value,StringFormat='C'}"/>

Result: Currency $6.25

 

Adding a Prefix or Suffix

<TextBlock Grid.Row="3">More Text</TextBlock>
<TextBlock Grid.Row="3" Grid.Column="1"
           Text="{Binding ElementName=MyValue,Path=Value,StringFormat='Just {0:C} each'}"/>

Result: More Text Just $6.25 each

 

Using a Custom Picture Format

<TextBlock Grid.Row="4">Customised</TextBlock>
<TextBlock Grid.Row="4" Grid.Column="1"
           Text="{Binding ElementName=MyValue,Path=Value,
           StringFormat='Decreased by {0:0.0}%'}"/>
<TextBlock Grid.Row="5">Customised (without prefix)</TextBlock>
<TextBlock Grid.Row="5" Grid.Column="1"
           Text="{Binding ElementName=MyValue,Path=Value,
           StringFormat='{}{0:0.0}% decrease'}"/>
OR
<TextBlock Grid.Row="5" Grid.Column="1"
           Text="{Binding ElementName=MyValue,Path=Value,
           StringFormat='{0:#,#.00}% decrease'}"/>

Result:
Customised Decreased by 6.25%
Customised(without prefix) 6.25% decrease

 

Creating Culture-Specific Data Bindings

<TextBlock Grid.Row="6">German Culture</TextBlock>
<TextBlock Grid.Row="6" Grid.Column="1"
           Text="{Binding ElementName=MyValue,Path=Value,
                          StringFormat='{}{0:C}',ConverterCulture=de-DE}"/>
<TextBlock Grid.Row="7">Japanese Culture</TextBlock>
<TextBlock Grid.Row="7" Grid.Column="1"
           Text="{Binding ElementName=MyValue,Path=Value,
                          StringFormat='{}{0:C}',ConverterCulture='ja-JP'}"/>

Result:
German Culture 6,25€
Japanese Culture 6¥‎

 

 

 

Using Interface as DataType for HierarchicalDataTemplate in TreeView

This can get a bit tricky if you are not careful. I ended up spending 2 hours to get this to work. Need to follow the following steps:

  1. Create a DataTemplateSelector. This basically means deriving from DataTemplateSelector class and overriding the SelectTemplate method.
  2. Add this class in resources section with a key
  3. Assign the above created resource key to ItemTemplateSelector attribute in XAML
  4. Most important, make sure that the point 3 above is done for <TreeViewItem> element and NOT for <HierarchicalDataTemplate>.

If you try to assign the ItemTemplateSelector anywhere else like inside <TreeView> element or inside <HierarchicalDataTemplate> then the worst part is that it will now show any compile time errors and during rendering, the overridden SelectTemplate() simply won’t get called and you might end up seeing just the ToString() implementation of the object which is usually the fully qualified object name

So be careful. The DataTemplateSelector class can be something like this:

public class InterfaceTemplateSelector : DataTemplateSelector
{

public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
FrameworkElement containerElement = container as FrameworkElement;

if (null == item || null == containerElement)
return base.SelectTemplate(item, container);

Type itemType = item.GetType();

IEnumerable<Type> dataTypes
= Enumerable.Repeat(itemType, 1).Concat(itemType.GetInterfaces());

DataTemplate template
= dataTypes.Select(t => new DataTemplateKey(t))
.Select(containerElement.TryFindResource)
.OfType<DataTemplate>()
.FirstOrDefault();

return template ?? base.SelectTemplate(item, container);

}
}

 

Applying String.Format on Numeric values

I was trying to apply String.Format on a textbox which was bound to double. The normal string.format functionality is that it will only work for strings, so i added a converter, still the value was not showing correctly formatted on the screen.

I was trying to show a “%” sign next to the value since it was a percentage information. Finally figured out that the correct escape sequence was missing hence the string.format was failing.

<TextBlock Text=”{Binding ElementName=BacktestAccuracySlider, Path=Value, Converter={StaticResource DoubleToStringConverter}, StringFormat=\{0\}%,FallbackValue=XX}”/>

That is the correct way to escape the fiddly StringFormat syntax.

Binding Mode for user control with ListBox within

I had a ListBox with Binding set on SelectedItem without explicitly setting it to TwoWay mode. Still this worked in two way mode without issues. When I moved that ListBox inside a usercontrol that’s when the binding stopped two way.

All i did was move the Listbox in usercontrol and created a dependency property in usercontrol to surface its properties to outside world. Internally usercontrol was binding to this dependency property using RelativeSource parent and externally we were just using the same binding code and assigning it to our newly created dependency property surfaced by usercontrol. Still, the default TwoWay binding stopped and I had to manually set mode=TwoWay to make it work.

Just a thought if somebody is wondering on the same issue.