Panel.ZIndex property in a treeviewitem in wpf - wpf

I Wish the treeviewitem to overlap the other items when i mouse hover it.
To do this i made the parent element (in my case its Border) within the HierarchicalDataTemplate to have the ZIndex as 0 and changed this value to 1 when the user hovers the mouse in the HierarchicalDataTemplate.Triggers section
<HierarchicalDataTemplate DataType="{x:Type d:MyClass}">
<Border Name="brd" CornerRadius="5" BorderThickness="1" Padding="3" Margin="0,0,60,0" Panel.ZIndex="0" >
<StackPanel Orientation="Horizontal" Margin="0,0,0,0" >
<Image Source="../Images/icon.jpg" Height="30"></Image>
<TextBlock TextAlignment="Center" Text="{Binding Text}"
Margin="3,0,10,0" >
</TextBlock>
<Image Margin="0,0,3,0"
Source="../Images/Img1.jpg" Height="30" />
<Image Margin="0,0,0,0"
Source="../Images/Img2" Height="30"/>
</StackPanel>
</Border>
<HierarchicalDataTemplate.Triggers>
<Trigger SourceName="brd" Property="IsMouseOver" Value="True">
<Setter TargetName="brd" Property="Panel.ZIndex" Value="1"></Setter>
</Trigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
The whole idea to implement this was:
Whenever the user hovers the mouse over a treeviewitem, the item should overlap the other controls and should be completely visible. Example: if the item is a long text, then the user should not be forced to use the scroll bar, rather if he just points it the item should be overlapping the other controls to display the complete item.
But i couldn't achieve this using the above triggers.
Please help me doing this.

Did you try using a ToolTip? I didn't try it myself but after seeing this I'm convinced that it's possible to define a DataTemplate which can be used at this property so the item is shown the way you like.
I hope this helps.
Regards

Related

Animating WPF Expander with XamlFlair

I cannot figure out how to animate WPF Expander with XamlFlair. My simplest template (should expand from top to bottom and contract to top):
<ControlTemplate TargetType="{x:Type Expander}">
<DockPanel>
<!-- EXPANDER HEADER -->
<ToggleButton x:Name="ExpanderButton"
DockPanel.Dock="Top"
HorizontalContentAlignment="Stretch"
IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
Content="Expand me"/>
<!-- EXPANDER CONTENT -->
<ContentPresenter x:Name="ExpanderContent"
DockPanel.Dock="Bottom"
xf:Animations.CombinedBinding="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
xf:Animations.Primary="{xf:Animate BasedOn={StaticResource ScaleFromTop}, Event=None, TransformOn=Layout}"
xf:Animations.Secondary="{xf:Animate BasedOn={StaticResource ScaleToTop}, Event=None, TransformOn=Layout}"
xf:Animations.StartWith="{StaticResource ScaleToTop}">
</ContentPresenter>
</DockPanel>
</ControlTemplate>
Problem is that no matter what initial IsExpanded property value is, Expander renders expanded at the beginning. When I add xf:Animations.StartWith="{StaticResource ScaleToTop}" (or ScaleFromTop - no mater which one) not only this does not fix the issue but also Expander's content is always blank.
Does anyone know how to make it work as expected? Thank you.
I was scratching my head for two days, figured out the solution 5 minutes after posting the question.
Did not use xf:Animations.StartWith, added this instead:
<ContentPresenter.LayoutTransform>
<ScaleTransform ScaleX="1" ScaleY="0" />
</ContentPresenter.LayoutTransform>

WPF IDataErrorInfo issues

I've used WPF and IDataErrorInfo in the past apps to display errors to the user via a controltemplate by putting an image in the adorner and adding a tooltip to the image like this;
<Style x:Key="textStyle" TargetType="TextBox">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<Border BorderBrush="Orange"
BorderThickness="2"
CornerRadius="4"
SnapsToDevicePixels="True">
<Border.Effect>
<DropShadowEffect BlurRadius="10"
ShadowDepth="0"
Color="Orange" />
</Border.Effect>
<DockPanel>
<Image Width="16"
Height="16"
Margin="-20,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
RenderOptions.BitmapScalingMode="HighQuality"
Source="{StaticResource imgError}"
ToolTip="{Binding ElementName=adornedElement,
Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent}"
ToolTipService.ShowDuration="30000" />
<AdornedElementPlaceholder Name="adornedElement" />
</DockPanel>
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
With the appropriate implementation of IDataErrorInfo in the ViewModel and setting Textbox in the view accordingly the image and tooltip are shown;
<TextBox Name="txt"
Grid.Column="0"
Height="40"
Background="Aqua"
Style="{StaticResource textStyle}"
Text="{Binding Path=Text,
UpdateSourceTrigger=PropertyChanged,
ValidatesOnDataErrors=True}" />
<TextBlock Grid.Column="1"
Height="40"
Background="AliceBlue"
Text="{Binding ElementName=txt,
Path=(Validation.Errors).CurrentItem.ErrorContent}" />
The above code displays correctly in my previous apps and shows the error in the image tooltip as confirmed by the Textblock.
However, in my current app which is built using Prism I can't get the Image to display. The TextBlock updates correctly and I can set the error to the TextBox tooltip via a style trigger without any issue. The problem is I can't seem to get the image (or anything else) to display in the Adorner. The Image is not shown and border is not changed.
The difference between previous apps and this is that the view is in a Region in a ContentControl and I've used dependency injection to inject the viewmodel into the view constructor and set the DataContext.
I can't figure out why this doesn't work when it did previously. I think I may need to include an AdornerDecorator somewhere but I'm perplexed as to where having tried it in a few places without success. Any ideas how I can ensure the Adorner is shown?
Used an AdornerDecorator to wrap the element containing the texbox and all works fine.

WPF "tooltip" popup flickers

Long story short: I have a window that displays a bunch of charts in a ListBox. When mouseOver a chart (with LineSeries), there is a line that follows the dataPoints (snaps to the dataPoint position). Near that line I'm presenting a tooltip made from a popup that presents info about those dataPoints.
So far so good. The problem is when I try to move the mouse over the toolTip, the popup starts flickering (like its in an open/close loop). I've set already on the popup and on the children IsHitTestVisible="False".
As a temp solution the popup "goes" out of the cursors way like here:
...but is hardly "understandable".
Now comes the question: what's wrong? Why the popup starts flickering when the mouse is over it.
Any feedback welcome
PS. The tooltips XAML (it's created in code, but here it is):
The chart's datacontext is data bound to a class, also some chart's events are imlemented throught icommands. The popup is created in the constructor of that class,
ppchart = New Popup() With {.AllowsTransparency = True, .IsHitTestVisible = False,.StaysOpen = True}
...in the MouseMoveCommand the popup's child is created:
Dim ppCont As XElement = <Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" IsHitTestVisible="False" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Rectangle Opacity="0.5" Grid.RowSpan="2" IsHitTestVisible="False" StrokeThickness="0" RadiusX="2" RadiusY="2" Fill="#FFBABABA"/>
<TextBlock Text="{Binding Over, StringFormat=HH:mm}" FontSize="9" TextAlignment="Center" FontFamily="Segoe UI" IsHitTestVisible="False" Margin="1"/>
<ListBox x:Name="listBox" ItemsSource="{Binding Points}" Background="{x:Null}" BorderBrush="{x:Null}" FontSize="8" Margin="1,0,1,1" Grid.Row="1" IsHitTestVisible="False" IsTextSearchEnabled="False" HorizontalAlignment="Stretch">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="IsHitTestVisible" Value="False"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid IsHitTestVisible="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Rectangle Fill="{Binding Culoare}" Width="3" HorizontalAlignment="Left" Margin="1" IsHitTestVisible="False"/>
<TextBlock Text="{Binding Operation}" HorizontalAlignment="Stretch" IsHitTestVisible="False" Grid.ColumnSpan="1" Grid.Column="1"/>
<TextBlock Text="{Binding points.Value}" HorizontalAlignment="Stretch" Grid.Column="2" TextAlignment="Right" IsHitTestVisible="False"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
ppchart.Effect = New Effects.DropShadowEffect() With {.Opacity = 0.5, .BlurRadius = 5, .Direction = 80, .Color = Colors.Black}
ppchart.Child = CType(XamlReader.Load(New XmlTextReader(New StringReader(ppCont.ToString))), UIElement)
reedited: this is how it looks like
I also faced a similar problem while using the MouseEnter and MouseLeave events. There is a strange behaviour of the MouseEnter event on WPF, don't know if it's a bug. When you enter the item in consideration from the top the flickering happens. Entering the item from any other direction gives you a smooth popup. So to avoid it, I removed the:
AllowsTransparency = True
part.
EDITED:
While still unable to find a perfect behaviour to my need, I figured out that this isn't actually a bug as described by Scott Hanselman here
However I wasn't able to compare the problem to mine and sort it out. Anyway, to have the animation features, I came up with a solution that would atleast reduce the extra opening or closure of the Popup control by checking the current position of the mouse. I defined a variable
Point currPoint = new Point();
And then in the MouseEnter event or handler:
ListViewItem listViewItem = e.Source as ListViewItem;
if(currPoint!=e.GetPosition(listViewItem))
compToStrategyVM.OpenPopup(listViewItem, listViewPopup);
Similarly in the MouseLeave event or handler:
ListViewItem listViewItem = e.Source as ListViewItem;
if (currPoint != e.GetPosition(listViewItem))
compToStrategyVM.ClosePopup(listViewPopup);
Here compToStrategyVM refers to my ViewMode and listViewPopup refers to the name of the Popup control. Though the issue still persists, but by this approach the flickering effect has been reduced to a considerable fraction.
After reading the comments I believe you are using the incorrect event; a MouseMove event will be continually trigged and with each time the popup to show/hide or flicker.
You want to use the MouseEnter and MouseLeave events.

Designing a custom edit control similar to hotmail style "To" box

I am desiging a custom control for use in my application which simulates a hotmail style "To" textbox which lets the user enter semicolon delimited strings. The control behaves like a textbox, on each ener press or entering semicolon a box(a textblock infact) gets created containing text entered which can be manipulated individually.
The control is implemented by means of a listview with its ItemPresenter set to a WrapPanel
The XAML looks like below:
<ListView x:Name="col" ItemContainerStyle="{StaticResource ContainerStyle}">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<local:MyWrapPanel Orientation="Horizontal" MinWidth="400"/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
<Style TargetType="{x:Type ListViewItem}" x:Key="ContainerStyle">
<Setter Property="ContentTemplate" Value="{StaticResource BoxView}" />
<Style.Triggers>
<Trigger Property="Tag" Value="Edit">
<Setter Property="ContentTemplate" Value="{StaticResource BoxViewEdit}" />
</Trigger>
</Style.Triggers>
</Style>
The control template for the listviewitems (boxes) looks like:
<DataTemplate x:Key="BoxView">
<Border BorderThickness="1" BorderBrush="Brown" Background="Beige" Margin="1,1,1,0" CornerRadius="6" >
<StackPanel Orientation="Horizontal">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Margin="5,5,5,0" Height="20" Text="{Binding XPath=''}"/>
<DockPanel Grid.Column="1" Grid.Row="0">
<Image Source="edit8.png" MouseLeftButtonUp="edit_MouseLeftButtonUp" ToolTip="Edit" Margin=" 10,0,0,0"></Image>
<Image Source="cancel8.png" MouseLeftButtonUp ="cancel_MouseLeftButtonUp" ToolTip="Remove" Margin=" 5,0,5,0"></Image>
</DockPanel>
</Grid>
</StackPanel>
</Border>
</DataTemplate>
Actually the listview is data bound to a set of xmlnodes having common parent.
The look and feel of the control has to be given such that it looks like a text box.
Now, I have the listview items bound to the xml nodes of an xml document, to show the textbox I add an empty xmlnode in the document and change the control template of the coressponding listviewitem so that it shows as a textbox.
On pressing enter in the text box a new xml node gets appended to the underlying xml at second last position containing innertext set to the textbox text(last positon is dummy node)
The template used for textbox is:
<DataTemplate x:Key="BoxViewEdit">
<TextBox Margin="0,5,5,0" Background="White" MaxWidth="400" BorderThickness="1" Text="{Binding XPath=''}"/>
</DataTemplate>
But the idea of adding an empty dummy xmlnode in the underlying source xml so that i could simulate editing of the listview seems hacky. Is there any cleaner way of doing this.
What i want is to wrap the text box as shown in figure with the contents of the wrappanel seamlessly without adding it to the wrappanel itself by means of creating a dummy xmlnode.
I had the same issue and found some solutions; you can check out the responses and comments here.

WPF Changing text in a controltemplate at run time

I am making a template control so that I can have a button with an image that changes when you click it. I also am trying to get text on top of the button that can change at run time. I have the button images and everything working but I can't seem to get that label at runtime so I can change the text. Here is the code in the xaml. I am missing the code behind
<UserControl.Resources>
<ControlTemplate TargetType="{x:Type Button}" x:Key="ActionButton">
<Grid>
<Label Panel.ZIndex="2" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Arial" Name="lblText" Foreground="#5E4421" FontWeight="Bold" FontSize="14">Test</Label>
<Image Name="Normal" Source="/AssaultWare.Controls;component/Replayer/Images/button_off.png"/>
<Image Name="Pressed" Source="/AssaultWare.Controls;component/Replayer/Images/button_on.png"/>
<Image Name="Disabled" Source="/AssaultWare.Controls;component/Replayer/Images/button_off.png" Visibility="Hidden"/>
</Grid>
<ControlTemplate.Triggers>
...
</ControlTemplate.Triggers>
</ControlTemplate>
</UserControl.Resources>
<Button Canvas.Left="471" Canvas.Top="465" Template="{StaticResource ActionButton}" Name="btnRight"/>
Difficult to decipher your question, but I think you just need to change the Label to a ContentControl and bind its Content property to the Button's Content property:
<ContentControl Content="{TemplateBinding Content}" .../>

Resources