I create in XAML RadGridVieaw controls custom tooltip and when tool tip before opening, I want read row and take ID and then load picture from database.
1 step I create custom tool tip
<Style TargetType="{x:Type telerik:GridViewRow}" BasedOn="{StaticResource GridViewRowStyle}" >
<Setter Property="ToolTipService.IsEnabled" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type telerik:RadGridView}}}" />
<Setter Property="ToolTip" >
<Setter.Value>
<ToolTip ToolTipService.ShowDuration="1000000" >
<Grid >
<Border HorizontalAlignment="Left" Height="170" Margin="5,0,0,0"
VerticalAlignment="Top" Width="130" BorderBrush="#FFCED8DA" BorderThickness="1" Padding="1">
<Image x:Name="GeneralTabItem_EmployeeImage" Source="{Binding CRAPhotoPhoto, Converter={StaticResource BinaryArrayToURIConverter}}" Stretch="UniformToFill"
Width="120" Height="160"/>
</Border>
<Grid/>
<telerik:RadGridView x:Name="ExtnedPrisonerInfoView_DataInput_ListGrid" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch" ToolTipService.ShowDuration="100000000"
DataContext="{Binding ''}" ToolTipOpening="OnContentChanged">
</telerik:RadGridView>
2 step I want to code behind catch event opening Tool tip.
3 step attach picture to the opening tool tip Image in Name="GeneralTabItem_EmployeeImage"
Please help me ToolTipOpening event is not working.
This should work as far as the event handler is concerned:
<Style TargetType="{x:Type telerik:GridViewRow}" BasedOn="{StaticResource GridViewRowStyle}" >
<EventSetter Event="ToolTipOpening" Handler="outerGrid_ToolTipOpening" />
...
But if you want to do something with the Image in the ToolTip, you need to wait until it has been created. You might as well handle the Loaded event of the Image and set the Source of it in there:
private void GeneralTabItem_EmployeeImage_Loaded(object sender, RoutedEventArgs e)
{
Image img = sender as Image;
//set source...
}
XAML:
<Setter Property="ToolTip" >
<Setter.Value>
<ToolTip ToolTipService.ShowDuration="1000000">
<Grid>
<Border HorizontalAlignment="Left" Height="170" Margin="5,0,0,0"
VerticalAlignment="Top" Width="130" BorderBrush="#FFCED8DA" BorderThickness="1" Padding="1">
<Image x:Name="GeneralTabItem_EmployeeImage" Stretch="UniformToFill"
Width="120" Height="160"
Loaded="GeneralTabItem_EmployeeImage_Loaded"/>
</Border>
<Grid/>
</Grid>
</ToolTip>
</Setter.Value>
</Setter>
Obviously you won't be able to set the Source property of an Image that resides in a ToolTip before the ToolTip has been opened because by then there is no Image. So this doesn't make much sense.
Create a simple tooltip first:
<Style TargetType="telerik:GridViewRow" BasedOn="{StaticResource
GridViewRowStyle}">
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip>
<TextBlock Text="{Binding EmployeeName}"></TextBlock>
</ToolTip>
</Setter.Value>
</Setter>
</Style>
Verify that works and if it does start adding more complex things like converters and ToolTipService stuff one at a time to see what is it exactly that is invalidating your XAML because XAML error is the only reason why the event would not be firing...
I need to reuse some vector images. I've implemented this using styles for a path setting the Data property.
When this style is applied in a DataTemplate set to a ListView, only the first item actually shows the path. The Path is visible in live outline during my debugging session. Design time it does show in each item.
I have already tried to make the style unshared using x:Shared="False" however this causes the hard to understand XBF generation error code 0x09c4. compile error.
<!-- Path Style defined in a seperate resource dictionary -->
<Style x:Key="Icon" TargetType="Path">
<Setter Property="Data" Value="F1 M32,32z M0,0z M8,7L8,8 8,9 5,9 4,9 4,10 4,24 4,25 5,25 27,25 28,25 28,24 28,10 28,9 27,9 24,9 24,8 24,7 23,7 19,7 18,7 18,8 18,9 14,9 14,8 14,7 13,7 9,7 8,7z M10,9L12,9 12,10 12,11 13,11 19,11 20,11 20,10 20,9 22,9 22,10 22,11 23,11 26,11 26,23 6,23 6,11 9,11 10,11 10,10 10,9z"/>
</Style>
<!-- DataTemplate defined in a seperate resource dictionary-->
<DataTemplate x:Key="ListViewItem">
<ViewBox>
<Path Style="{StaticResource Icon}" Fill="{StaticResource IconBrush}"/>
</ViewBox>
</DataTemplate>
<!-- DataTemplate applied on a page -->
<ListView
ItemTemplate="{StaticResource ListViewItem}"
ItemsSource={Binding Items}>
</ListView>
Does anyone have any ideas about what might cause this behaviour and how it can be solved?
This is a known issue since the days with Silverlight. When used inside a style, the Path will only be instantiated once. Unlike in WPF, there's no x:Shared="False" to force creating a new instance every time it's requested.
That leaves you with three other options.
First, you can use the Path directly inside your DataTemplate.
<DataTemplate x:Key="ListViewItem">
<Viewbox>
<Path Data="F1 M32,32z M0,0z M8,7L8,8 8,9 5,9 4,9 4,10 4,24 4,25 5,25 27,25 28,25 28,24 28,10 28,9 27,9 24,9 24,8 24,7 23,7 19,7 18,7 18,8 18,9 14,9 14,8 14,7 13,7 9,7 8,7z M10,9L12,9 12,10 12,11 13,11 19,11 20,11 20,10 20,9 22,9 22,10 22,11 23,11 26,11 26,23 6,23 6,11 9,11 10,11 10,10 10,9z" Fill="Red"/>
</Viewbox>
</DataTemplate>
For more flexibility, you can also use a ContentControl instead.
<Style x:Key="Icon" TargetType="ContentControl">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Path Fill="Red" Data="F1 M32,32z M0,0z M8,7L8,8 8,9 5,9 4,9 4,10 4,24 4,25 5,25 27,25 28,25 28,24 28,10 28,9 27,9 24,9 24,8 24,7 23,7 19,7 18,7 18,8 18,9 14,9 14,8 14,7 13,7 9,7 8,7z M10,9L12,9 12,10 12,11 13,11 19,11 20,11 20,10 20,9 22,9 22,10 22,11 23,11 26,11 26,23 6,23 6,11 9,11 10,11 10,10 10,9z"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="ListViewItem">
<Viewbox>
<ContentControl Style="{StaticResource Icon}"/>
</Viewbox>
</DataTemplate>
The last one is probably the best but it will require some work to change the Data property to a more specific PathGeometry.
<Style x:Key="Icon" TargetType="Path">
<Setter Property="Data">
<Setter.Value>
<PathGeometry FillRule="EvenOdd">
<PathFigure IsClosed="True" StartPoint="0,0">
<LineSegment Point="xxx,xxx" />
<LineSegment Point="xxx,xxx" />
</PathFigure>
</PathGeometry>
</Setter.Value>
</Setter>
</Style>
How can I get the binding from the outer ConnectingLine (a custom control that binds to FrameworkElements and connects them with a line) to the inner TextBlocks named "Top" and "Bottom" to work? Note that I want the whole FrameworkElements for position information.
<Grid>
<ConnectingLine From="{Binding ElementName=Button1.Top}" To="{Binding ElementName=Button2.Top}" />
<ConnectingLine From="{Binding ElementName=Button1.Bottom}" To="{Binding ElementName=Button2.Bottom}" />
<ToggleButton x:Name="Button1">
<ToggleButton.Template>
<ControlTemplate>
<Grid>
<Rectangle x:Name="Top" />
<Rectangle x:Name="Bottom" />
</Grid>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<ToggleButton x:Name="Button2">
<ToggleButton.Template>
<ControlTemplate>
<Grid>
<Rectangle x:Name="Top" />
<Rectangle x:Name="Bottom" />
</Grid>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
</Grid>
My goal is to be able to bind from within XAML. Ideally with no extra fluff, but a solution involving a custom binding operator or attached properties might be acceptable.
Edit:
How I'd like to have the output:
Each distinct colored column is one of the templated ToggleButtons, already with one dashed ConnectingLine between Top and Bottom elements. The horizontal filled lines are what I'm interested in. Currently I'm achieving what I want from code-behind.
<ToggleButton x:Name="Button">
<ToggleButton.Template>
<ControlTemplate>
<Grid>
<CheckBox x:Name="FindMe" IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsChecked}"/>
</Grid>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
Let me know if it works.
I have a custom tooltip style that basically creates a nice black tooltip with an arrow pointing to the location of the item you hovered over.
The problem is that sometimes the tooltip will not always be placed in the correct location (i.e. near window edges) which means the tooltip arrow no longer points at the correct place... Is there anyway around this problem? Or can I create specific styles for each location placement?
<Style x:Key="{x:Type ToolTip}" TargetType="ToolTip">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="HasDropShadow" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<StackPanel>
<Border CornerRadius="3" HorizontalAlignment="Center" VerticalAlignment="Top" Padding="10,7" BorderThickness="0" Background="#e5323232">
<StackPanel>
<TextBlock FontFamily="Arial" FontSize="12" Text="{TemplateBinding Content}" Foreground="#f0f0f0" />
</StackPanel>
</Border>
<Path Margin="10,0,0,0" Fill="#e5323232" Data="M 0 0 L 6 6 L 12 0 Z"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
Maybe you could try this, I just set the Placement to Center and added a HorizontalOffset to match the arrow you created in the template.
However that wont center it vertically on the control, so you could make an IValueConverter and calculate the size of the control and divide by 2, or you could add a dummy element to your StackPanel that is the same size as the Border, and that should center the ToolTip without needing any code behind
<Style TargetType="{x:Type ToolTip}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="HasDropShadow" Value="True"/>
<Setter Property="Placement" Value="Center" />
<!--Offset to the arrow path-->
<Setter Property="HorizontalOffset" Value="15"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}">
<StackPanel>
<Border x:Name="border" CornerRadius="3" HorizontalAlignment="Center" VerticalAlignment="Top" Padding="10,7" BorderThickness="0" Background="#e5323232">
<StackPanel>
<TextBlock FontFamily="Arial" FontSize="12" Text="{TemplateBinding Content}" Foreground="#f0f0f0" />
</StackPanel>
</Border>
<Path Margin="10,0,0,0" Fill="#e5323232" Data="M 0 0 L 6 6 L 12 0 Z"/>
<!--Dummy rectangle same height as tool tip, so it centers on the control-->
<Rectangle Height="{Binding ActualHeight, ElementName=border}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The simplest way of doing it is to use a UIElement that exists in the Control Tree as the PlacementTarget of the Tooltip. This will avoid the Silverlight automated positioning when you get near the window edges:
<StackPanel ToolTipService.ToolTip="{Binding Title, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"
ToolTipService.Placement="Bottom"
ToolTipService.PlacementTarget="{Binding ElementName=LayoutRoot}">
<TextBlock Text="{Binding Title,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
In this case the tooltip will be positioned always at the Origin of the LayoutRoot element. If you have a fixed path size and the PlacementTarget is always at the same position relative to the control for which you want to show the tooltip then this works fine.
If you need to position the Tooltip relatively to the control that triggers the Tooltip than you have to make the Path Data dynamic and calculate the distance to create a new Path Data in the Tooltip control every time the Tooltip is opened.
For this case you have to handle the Tooltip.IsOpened event and implement this logic. If you're using the PlacementTarget than you always know the direction relatively to your control so this makes it easier to calculate the Path vertices.
Another way which works but it's way more complex is to implement your own Popup that shows up when you move the mouse over your control. You would need to implement a few calculations to get the position of the popup relative to the Control, which is exactly what the Tooltip control does for you. The advantage of this is that you have complete control over the positioning of the tooltip and its appearance.
I've got some windows with mainly comboboxes, textboxes, and checkboxes. When you click on one to get focus I need a way to have them be outlined with a colorful box (boss' orders). Is there a way to do this easier than overriding the default style of all of these controls? I've never done that before, so it would take a lot of mucking around on my part to figure it out.
You can try adding a FocusVisualStyle to the Controls that need different focus rectangle styles.
From above link
The second mechanism is to provide a separate style as the value of the FocusVisualStyle property; the "focus visual style" creates a separate visual tree for an adorner that draws on top of the control, rather than changing the visual tree of the control or other UI element by replacing it.
Something like this in your Window's Xaml
<Window.Resources>
<Style x:Key="NewFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<Rectangle Stroke="Red" Margin="2" StrokeThickness="1" StrokeDashArray="1 2" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
or your Application.Xaml file.
<Application.Resources>
<Style x:Key="NewFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<Rectangle Stroke="Red" Margin="2" StrokeThickness="1" StrokeDashArray="1 2" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
Usage:
<ComboBox FocusVisualStyle="{StaticResource NewFocusVisual}" Height="23" HorizontalAlignment="Left" Margin="238,102,0,0" Name="ComboBox1" VerticalAlignment="Top" Width="120" />
<CheckBox FocusVisualStyle="{StaticResource NewFocusVisual}" Content="CheckBox" Height="16" HorizontalAlignment="Left" Margin="238,71,0,0" Name="CheckBox2" VerticalAlignment="Top" />
<TextBox FocusVisualStyle="{StaticResource NewFocusVisual}" Height="23" HorizontalAlignment="Left" Margin="238,144,0,0" Name="TextBox1" VerticalAlignment="Top" Width="120" />
If you want the Focus rectangle to change for every type of focus event Microsoft states that:
From Microsoft: Focus visual styles act exclusively for keyboard focus. As such, focus visual styles are a type of accessibility feature. If you want UI changes for any type of focus, whether via mouse, keyboard, or programmatically, then you should not use focus visual styles, and should instead use setters and triggers in styles or templates that are working from the value of general focus properties such as IsFocused or IsFocusWithin.
Give this a shot it works for a TextBox haven't checked your other Controls
<Application.Resources>
<Style TargetType="TextBox" >
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Control.BorderBrush" Value="Red" />
<Setter Property="Control.BorderThickness" Value="3" />
</Trigger>
</Style.Triggers>
</Style>
</Application.Resources>