I'm using MahApps.Metro 1.3.0 and have a problem with a smaller clickable area of controls at the edge of the window, but if I move them away from the edge of the window the clickable area goes back to normal.
Is there any way to fix this?
My scrollviewer xaml:
<ScrollViewer x:Name="ScrollViewer" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto">
<ItemsControl x:Name="DocumentList" ItemsSource="{Binding Source={StaticResource Documents}}" BorderBrush="{x:Null}" ScrollViewer.CanContentScroll="False" Margin="0,0,0,1">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock>
<Hyperlink Command="{Binding DataContext.OpenCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" CommandParameter="{Binding UNID}">
<InlineUIContainer>
<TextBlock Text="{Binding DisplayName}" />
</InlineUIContainer>
</Hyperlink>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander Header="{Binding Name}" IsExpanded="False">
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ItemsControl.GroupStyle>
</ItemsControl>
</ScrollViewer>
And my window xaml:
<Controls:MetroWindow x:Class="MainWindow"
Name="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:data="clr-namespace:System.Windows.Data;assembly=PresentationFramework"
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
BorderBrush="{DynamicResource AccentColorBrush}" BorderThickness="1 0 1 1"
Title="" Height="318" Width="526"
ShowIconOnTitleBar="False"
ResizeMode="NoResize"
Cursor="{Binding Cursor}"
NonActiveWindowTitleBrush="{StaticResource InactiveBlueColorBrush}">
Related
How can I make the ListView/Layout scroller to behave like modern layout like in android or windows 10. Currently the ListView scrollbar only applies to the ListView itself. I want the scroller to scroll the whole layout including the search bar in XAML.
I want also the ListView Items added to increment to the overall height of the ListView to achieve the effect.
Any available ways to do it with Native wpf xaml (No frameworks/dlls, just pure xaml/c#)
Code:
<local:BasePage x:Class="GeneralMerchandise.UI.Pages.UsersPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:a="clr-namespace:GeneralMerchandise.UI.AttachedProperties"
xmlns:local="clr-namespace:GeneralMerchandise.UI.Pages"
xmlns:c="clr-namespace:GeneralMerchandise.UI.Converter"
xmlns:viewmodel="clr-namespace:GeneralMerchandise.UI.ViewModel"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="UsersPage">
<Page.DataContext>
<viewmodel:UsersViewModel x:Name="VM"/>
</Page.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Orientation="Vertical"
Grid.Row="0"
Background="{StaticResource DefaultBackground}">
<TextBlock FontSize="{StaticResource FontSizeXLarge}"
Text="Users" />
<Border BorderThickness="0 0 0 1">
<Grid>
<StackPanel Orientation="Vertical" Width="300">
<TextBox Style="{StaticResource FlatTextBox}"
Width="270"
Margin="8"
a:Hint.TextProperty="Search"
a:ClearableText.EnableClearTextProperty="True"
Text="{Binding Search, UpdateSourceTrigger=PropertyChanged}"/>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center">
<StackPanel.Resources>
<Style TargetType="RadioButton" BasedOn="{StaticResource FlatToggle}">
<Setter Property="Padding"
Value="15 10"/>
<Setter Property="BorderThickness"
Value="0 0 0 3"/>
</Style>
</StackPanel.Resources>
<RadioButton GroupName="Filter"
Content="All"
IsChecked="True"
Command="{Binding FilterActiveCommand}"
CommandParameter="{x:Static viewmodel:UsersViewModel+FilterActiveProperty.None }"/>
<RadioButton GroupName="Filter"
Content="Active"
Command="{Binding FilterActiveCommand}"
CommandParameter="{x:Static viewmodel:UsersViewModel+FilterActiveProperty.Active }"/>
<RadioButton GroupName="Filter"
Content="Deactived"
Command="{Binding FilterActiveCommand}"
CommandParameter="{x:Static viewmodel:UsersViewModel+FilterActiveProperty.Deactivated }"/>
</StackPanel>
</StackPanel>
<Button DockPanel.Dock="Right"
Content="New"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Command="{Binding NewUserCommand}"/>
</Grid>
</Border>
</StackPanel>
<ListView Grid.Row="2"
Background="Transparent"
ItemsSource="{Binding UsersDisplay}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto"
BorderThickness="0"
Padding="20">
<ListView.Resources>
<c:UserDisplayDataFullnameConverter x:Key="FullnameConverter"/>
<c:BoolToValueConverter TrueValue="Active" FalseValue="Deactivated" x:Key="BoolToStringConverter"/>
</ListView.Resources>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel HorizontalAlignment="Left" Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Button Style="{StaticResource PlainButton}"
Background="White"
DataContext="{Binding}"
Width="250"
Height="150"
Padding="5"
BorderThickness="2"
Margin="{StaticResource MarginSmall}"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch">
<Button.ToolTip>
<ToolTip>
<TextBlock Text="NAME"/>
</ToolTip>
</Button.ToolTip>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Ellipse Grid.Column="0"
Margin="5"
VerticalAlignment="Top"
Height="{Binding Path=ActualWidth, RelativeSource={RelativeSource Self}}"
Fill="{StaticResource LightGrayBrush}"/>
<Ellipse Grid.Column="0"
Margin="5"
VerticalAlignment="Top"
x:Name="userPicturePopup"
Height="{Binding Path=ActualWidth, RelativeSource={RelativeSource Self}}"
Width="Auto">
<Ellipse.Fill>
<ImageBrush ImageSource="{StaticResource UserIconMedium}"/>
</Ellipse.Fill>
</Ellipse>
<StackPanel Grid.Column="1"
Orientation="Vertical">
<TextBlock Text="{Binding Converter={StaticResource FullnameConverter}}"
TextWrapping="WrapWithOverflow"
Margin="10 5"/>
<TextBlock Margin="10 5"
Text="{Binding Created, StringFormat=Created {0:d}}"/>
<TextBlock Margin="10 5"
Text="{Binding IsActive, Converter={StaticResource BoolToStringConverter}, StringFormat=Account Is {0}}"/>
</StackPanel>
</Grid>
</Button>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border BorderBrush="Transparent"
BorderThickness="3"
Background="{TemplateBinding Background}">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</Grid>
Put your ListView, search bar, and whatever else you want to scroll inside of a ScrollViewer.
Problem:
I have a ListBox in which I display my data using DataBinding. The data is displayed as a custom view SystemEnvironmentElementView.
I want to allow the user to rename single elements. This should happen in the ViewModel of the desired element.
I created a ContextMenu in the View that displays my data. However when I right click on my element the ContextMenu is not displayed. I also encountered the problem that on my PreviewMouseDown event handler I don't get the view as OriginalSource in the EventArgs but a Border.
Question:
How do I get the ContextMenu of my element to show?
ListBox Code:
<customControls:ListBoxNoDragSelection ItemsSource="{Binding Elements}" Background="{DynamicResource BG}" SelectedItem="{Binding SystemEnviromentAnalysis.SelectedElement}"
BorderThickness="0" x:Name="ListBoxNoDragSelection" SelectedValue="{Binding SelectedElement}">
<i:Interaction.Behaviors>
<dragAndDrop:FrameworkElementDropBehaviorWithMousePos />
</i:Interaction.Behaviors>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="{DynamicResource MyVisualBrush}"
Height="Auto" Width="Auto" PreviewMouseLeftButtonDown="UIElement_OnPreviewMouseLeftButtonDown"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Canvas.Left" Value="{Binding Element.X}"/>
<Setter Property="Canvas.Top" Value="{Binding Element.Y}"/>
<Setter Property="Canvas.ZIndex" Value="{Binding Element.Z}"/>
<Setter Property="Height" Value="Auto"/>
<Setter Property="Width" Value="Auto"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<systemEnvironment:SystemEnvironmentElementView/>
</DataTemplate>
</ListBox.ItemTemplate>
</customControls:ListBoxNoDragSelection>
SystemEnviromentElementView:
<UserControl x:Class="TestApp.Editor.Views.SystemEnvironment.SystemEnvironmentElementView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Height="Auto" Width="Auto">
<UserControl.ContextMenu>
<ContextMenu>
<MenuItem Header="Rename"/>
</ContextMenu>
</UserControl.ContextMenu>
<StackPanel>
<Image Height="{Binding Element.Height}" Width="{Binding Element.Width}" Grid.Row="0" Source="{Binding Element.Icon}" IsHitTestVisible="False"/>
<Label Height="Auto" Width="Auto" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" IsHitTestVisible="False"
Content="{Binding Element.Name}"/>
</StackPanel>
I need some advice. We noticed unusual behavior within the ScrollViewer. I have a StackPanel with whom I am more items including ListBox when the StackPanel placed in a ScrollViewer, when loading data to the listbox, a program for a brief moment freezes. When I am alone ListBox but everything works normally, no freezing of the program.
Here is my code:
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel x:Name="tStack" >
<Grid Height="300">
</Grid>
<Grid Height="300">
</Grid>
<ListBox x:Name="ListBox1" ItemsSource="{Binding AlbumsCvs.View, IsAsync=True}"
Style="{StaticResource ListBoxAlbumsTracksStyles}"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
VirtualizingStackPanel.VirtualizationMode="Recycling" >
<ListBox.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource AlbumsHeader}" />
</ListBox.GroupStyle>
</ListBox>
</StackPanel>
</ScrollViewer>
<Style x:Key="ListBoxAlbumsTracksStyles" TargetType="{x:Type ListBox}">
<Setter Property="Padding" Value="0,0,0,0" />
<Setter Property="Margin" Value="0,0,0,0" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate >
<DockPanel>
<Border Background="#00000000"
Height="36"
Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}}">
<DockPanel>
<TextBlock x:Name="TrackNumber"
DockPanel.Dock="Left" Margin="2,0,5,0"
Text="{Binding TrackNumber}"
VerticalAlignment="Center"
FontSize="13"
MinWidth="17"
Foreground="Black"/>
<DockPanel>
<TextBlock DockPanel.Dock="Left"
Text="{Binding TrackTitle}"
TextAlignment="Left"
FontSize="13"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
TextTrimming="CharacterEllipsis"
Margin="0,0,2,0"/>
<TextBlock DockPanel.Dock="Right"
Text="{Binding Duration}"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
TextTrimming="CharacterEllipsis"
Margin="0,0,10,0"
FontSize="13" TextAlignment="Right"/>
</DockPanel>
</DockPanel>
</Border>
</DockPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- GroupItem -->
<Style x:Key="AlbumsHeader" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}}" Background="#00000000">
<StackPanel Margin="0,0,0,15">
<StackPanel>
<TextBlock Text="{Binding AlbumName}"
DataContext="{Binding Items}"
Margin="0,5,0,0"
HorizontalAlignment="Stretch"
FontSize="20"
FontWeight="Light"
TextTrimming="CharacterEllipsis"
Foreground="Black"/>
<TextBlock Text="{Binding IdAlbum}"
DataContext="{Binding Items}"
Margin="0,0,0,10"
HorizontalAlignment="Stretch"
TextTrimming="CharacterEllipsis"
Foreground="Black"/>
</StackPanel>
<ItemsPresenter HorizontalAlignment="Stretch"/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
code behind:
private async Task AlbumsArtistInformation()
{
if (string.IsNullOrEmpty(ArtistName))
return;
ObservableCollection<AlbumsArtistCollections> _albumsArtistCollections =
new ObservableCollection<AlbumsArtistCollections>();
try
{
var search = await spotifyDataService.GetArtists(ArtistName);
if (search == null) throw new ArgumentNullException(nameof(search));
foreach (var _artist in search.Artists.Items.Take(1))
{
this.IdArtist = _artist.Id;
}
var _artistAlbum = await spotifyDataService.GetArtistsAlbumsAsync(this.IdArtist, AlbumType.All);
if (_artistAlbum == null) throw new ArgumentNullException(nameof(_artistAlbum));
_albumsArtistCollections = _artistAlbum;
}
finally
{
// Unbind to improve UI performance
Application.Current.Dispatcher.Invoke(() =>
{
this.Albums = null;
this.AlbumsCvs = null;
});
Application.Current.Dispatcher.Invoke(() =>
{
this.Albums = _albumsArtistCollections;
});
Application.Current.Dispatcher.Invoke(() =>
{
// Populate CollectionViewSource
this.AlbumsCvs = new CollectionViewSource { Source = this.Albums };
//Group by Album if needed
this.AlbumsCvs.GroupDescriptions.Add(new PropertyGroupDescription("IdAlbum"));
});
}
}
Does anyone know how to solve this problem.
Vertically oriented StackPanel provides an unbounded available space for the the ListBox, when it calls MeasureOverride(Size availableSize) method, during layout. Therefore, the ListBox (which by default uses virtualization) should create the whole items and this is why you program freezes for a moment.
Therefore, use a DockPanel instead:
<DockPanel x:Name="tStack" LastChildFill="True" >
<Grid DockPanel.Dock="Top" Height="300">
</Grid>
<Grid DockPanel.Dock="Top" Height="300">
</Grid>
<ListBox DockPanel.Dock="Bottom" x:Name="ListBox1" ItemsSource="{Binding AlbumsCvs.View, IsAsync=True}"
Style="{StaticResource ListBoxAlbumsTracksStyles}"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
VirtualizingStackPanel.VirtualizationMode="Recycling" >
<ListBox.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource AlbumsHeader}" />
</ListBox.GroupStyle>
</ListBox>
</DockPanel>
LastChildFill is true by default. The ListBox should be the last element, in order to fill the space.
As another option, you can set the Height of the ListBox and put the DockPanel in a ScrollViewer or you can consider a Grid with splitters as another option.
Maybe this is a stupid asking, but I just wonder how to design this kind of layout:
first of all, I have a MenuList ObservableCollection. So I have to put these menus in to a stackPanel like this:
<Window.Resources>
<DataTemplate x:Key="MenuItemTemplate">
<Button Content="{Binding ContentText}" Panel.ZIndex="{Binding PIndex}" Padding="10" FontSize="20"/>
</DataTemplate>
</Window.Resources>
<ItemsControl ItemsSource="{Binding Menus}" ItemTemplate="{StaticResource MenuItemTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
so it looks like this:
after a while, there's a new bar under this menu added in:
<ItemsControl ItemsSource="{Binding Menus}" ItemTemplate="{StaticResource MenuItemTemplate}">
.......
</ItemsControl>
<Border Background="Green" VerticalAlignment="Top" Panel.ZIndex="10" Height="30" Margin="0,81,0,0"/>
Now it's look like this:
The requirment is, if a button selected, it should on the top of the bar, other unselected buttons should be covered by the bar:
But the buttons' are in a StackPanel, so they're all based on StackPanel's ZIndex.
My question is, how to design such layout in xaml?
I think using the renderTransform is better. No need to hard code PIndex in xaml. See below.
<DataTemplate x:Key="MenuItemTemplate">
<Button Content="{Binding}" Padding="10" FontSize="20" Height="30" Width="100">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="1" ScaleY="1.2"></ScaleTransform>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DataTemplate>
<Border Background="Green" VerticalAlignment="Top" Height="30" Margin="0,150,0,0"/>
<ItemsControl ItemsSource="{Binding Menus}" ItemTemplate="{StaticResource MenuItemTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Code behind:
public ObservableCollection<string> Menus { get; set; }
EDIT:
<DataTemplate x:Key="MenuItemTemplate">
<Button Content="{StaticResource image1}" Height="30" Width="100">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Border x:Name="Border" Height="{TemplateBinding Height}"
Width="{TemplateBinding Width}" Background="Orange">
</Border>
<ContentPresenter ContentSource="Content" HorizontalAlignment="Stretch" VerticalAlignment="Top"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="RenderTransform" TargetName="Border">
<Setter.Value>
<ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="1" ScaleY="1.2"></ScaleTransform>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DataTemplate>
If the bar is literally just a green bar, you can also put it on the DataTemplate as a separate Stackpanel from the button, and then put a Style.Trigger on the Button's stackpanel to increase the ZIndex OnMouseOver. The bar would look seamless even if it is just repeating.
So instead of:
<DataTemplate x:Key="MenuItemTemplate">
<Button Content="{Binding ContentText}" Panel.ZIndex="{Binding PIndex}" Padding="10" FontSize="20"/>
</DataTemplate>
You will have
<DataTemplate x:Key="MenuItemTemplate">
<Grid>
<StackPanel >
<StackPanel.Style>
<Style TargetType="StackPanel" >
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="3"></Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Panel.ZIndex" Value="1"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<Button Width="100" Height="100" Content="{Binding ContentText}" Padding="10" FontSize="20" />
</StackPanel>
<StackPanel Panel.ZIndex="2">
<Border Background="Green" VerticalAlignment="Top" Height="30"/>
</StackPanel>
</Grid>
</DataTemplate>
(This doesn't look quite perfect if you run it, but you get the idea)
Dockpanel as our ItemPanelTemplate is the right choice.
Use a Grid with Button and Rectangle (for bottom border) as DataTemplate to show Menu items.
Don't apply margin in DataTemplate's Grid in step2 above. Instead use Grid Padding, Button margin for spacing.
DataTemplate :
<DataTemplate x:Key="MenuItemTemplate">
<Grid Background="DodgerBlue">
<Button Margin="5 5 5 0" HorizontalAlignment="Left" Panel.ZIndex="1" Content="{Binding ContentText}" Padding="1" Width="75" GotKeyboardFocus="Button_GotKeyboardFocus" LostKeyboardFocus="Button_LostKeyboardFocus"/>
<Rectangle Panel.ZIndex="2" Fill="BurlyWood" Height="5" Margin="0 25 0 0"/>
</Grid>
</DataTemplate>
ItemPanelTemplate :
<ItemsPanelTemplate>
<DockPanel Height="30" LastChildFill="True"/>
</ItemsPanelTemplate>
Use the below code as is :
<ItemsControl Panel.ZIndex="10" VerticalAlignment="Top" ItemsSource="{Binding Menus}" ItemTemplate="{DynamicResource MenuItemTemplate}" Margin="0">
<ItemsControl.Resources>
<DataTemplate x:Key="MenuItemTemplate">
<Grid Background="DodgerBlue">
<Button Margin="0" HorizontalAlignment="Left" Panel.ZIndex="1" Content="{Binding ContentText}" Padding="1" Width="75" GotKeyboardFocus="Button_GotKeyboardFocus" LostKeyboardFocus="Button_LostKeyboardFocus"/>
<Rectangle Panel.ZIndex="2" Fill="BurlyWood" Height="5" Margin="0 25 0 0"/>
</Grid>
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel Height="30" LastChildFill="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Code-Behind
public IList Menus { get; set; }
public Window1()
{
InitializeComponent();
Menus = new[] { new { ContentText = "Menu1" }, new { ContentText = "Menu2" }, new { ContentText = "Menu3" } };
this.DataContext = this;
}
private void Button_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
Panel.SetZIndex((Button)e.OriginalSource, 12);
}
private void Button_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
Panel.SetZIndex((Button)e.OriginalSource, 1);
}
i have one problem with tooltip.
I want to add templated tooltip to button with some information inside.
Here the button with tooltip, which datacontext bounded to some viewmodel:
<fluent:Button DataContext="{Binding NewConnections, Source={StaticResource Locator}}" Command="{Binding AddCloudStorageAccount}" Header="Add Account">
<fluent:Button.LargeIcon>
<Image Source="pack://application:,,,/Icons;component/UI/v1/add_account.png" Width="48"/>
</fluent:Button.LargeIcon>
<fluent:Button.ToolTip>
<ToolTip DataContext="{Binding UserInput.AddAccountsButtonInfo, Source={StaticResource Locator}}" Style="{StaticResource ButtonTooltip}"></ToolTip>
</fluent:Button.ToolTip>
</fluent:Button>
Style:
<Style TargetType="ToolTip" x:Key="ButtonTooltip">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border Background="LightYellow" BorderThickness="0.5" BorderBrush="Maroon">
<StackPanel Orientation="Vertical" Margin="3">
<TextBlock x:Name="_txtText" Text="{Binding Title}"></TextBlock>
<TextBlock x:Name="_txtDescription" Margin="0 10 0 0" Text="{Binding Description}"></TextBlock>
<TextBlock x:Name="_txtHotKeyDescription" Margin="0 10 0 0" Text="{Binding HotKeyDescription}"></TextBlock>
</StackPanel>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
I set some breakpoints to see if viewmodel is accessed. And it's ok. But properties like Title not accessed at all and i see only empty rectangle without any text
Do someone have some ideas?
Just resolved it(set datacontext in border). Maybe someone will be interested in:
<Style TargetType="ToolTip" x:Key="ButtonTooltip">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border Background="LightYellow" BorderThickness="0.5" BorderBrush="Maroon" DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ToolTip}}}">
<StackPanel Orientation="Vertical" Margin="3">
<TextBlock x:Name="_txtText" Text="{Binding Title}"></TextBlock>
<TextBlock x:Name="_txtDescription" Margin="0 10 0 0" Text="{Binding Description}"></TextBlock>
<TextBlock x:Name="_txtHotKeyDescription" Margin="0 10 0 0" Text="{Binding HotKeyDescription}"></TextBlock>
</StackPanel>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>