In AvalonDock we use a LayoutDocumentExtended to add some AdditionalInformation (not only a string in our project) in the Title.
In this testcode, we set the DocumentHeaderTemplate as following.
<xcad:DockingManager.DocumentHeaderTemplate>
<DataTemplate DataType="{x:Type local:LayoutDocumentExtended}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title, StringFormat={}{0} ---- }" />
<TextBlock Text="{Binding AdditionalString}" />
</StackPanel>
</DataTemplate>
</xcad:DockingManager.DocumentHeaderTemplate>
<xcad:LayoutRoot>
<xcad:LayoutPanel Orientation="Vertical" >
<xcad:LayoutDocumentPane>
<xcad:LayoutDocumentPane.Children>
<local:LayoutDocumentExtended Title="Test1" AdditionalString="848451"> </local:LayoutDocumentExtended>
<local:LayoutDocumentExtended Title="Test2" AdditionalString="1"></local:LayoutDocumentExtended>
</xcad:LayoutDocumentPane.Children>
</xcad:LayoutDocumentPane>
</xcad:LayoutPanel>
</xcad:LayoutRoot>
If i undock the LayoutDocument as a FloatingWindow, only the Title shows up and not the AdditionalString. As soon as I redock it again, the AdditionalString is shown again. Does someone have an idea, how I can set a configurable DocumentHeaderTemplate also on FloatingWindows?
The LayoutDocumentFloatingWindowControl control uses the WindowChrome to define the title bar. You probably want to modify the title bar of the chrome to allow it to show additional vertical content i.e. extra lines. Alternatively, consider to show the extra information in parenthesis and in the same single line.
Override the DocumentTitleTemplate to layout the title:
<DataTemplate x:Key="DocumentTitleTemplate">
<TextBlock Text="{Binding Title}"
TextTrimming="CharacterEllipsis">
</TextBlock>
</DataTemplate>
The override the LayoutDocumentFloatingWindowControl style to modify the title bar height:
<Style x:Key="{x:Type avalonDockControls:LayoutDocumentFloatingWindowControl}"
TargetType="{x:Type avalonDockControls:LayoutDocumentFloatingWindowControl}">
<Setter Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
<Setter Property="BorderBrush"
Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" />
<Setter Property="BorderThickness"
Value="3" />
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome ResizeBorderThickness="10"
CaptionHeight="16"
CornerRadius="3,3,3,3"
GlassFrameThickness="0"
ShowSystemMenu="False" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type avalonDockControls:LayoutDocumentFloatingWindowControl}">
<AdornerDecorator>
<Grid>
<Border x:Name="WindowBorder"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}">
<Grid Margin="3">
<Grid.RowDefinitions>
<RowDefinition MinHeight="16"
Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid UseLayoutRounding="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter Content="{Binding Model.RootDocument, RelativeSource={RelativeSource TemplatedParent}}"
ContentTemplate="{Binding Model.Root.Manager.DocumentTitleTemplate, RelativeSource={RelativeSource TemplatedParent}}"
ContentTemplateSelector="{Binding Model.Root.Manager.DocumentTitleTemplateSelector, RelativeSource={RelativeSource TemplatedParent}}" />
<Button shell:WindowChrome.IsHitTestVisibleInChrome="True"
Focusable="False"
Visibility="{Binding IsMaximized, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolToVisibilityConverter}}"
Style="{DynamicResource {x:Static ToolBar.ButtonStyleKey}}"
Command="{x:Static shell:SystemCommands.MaximizeWindowCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource TemplatedParent}}"
ToolTip="{x:Static avalonDockProperties:Resources.Window_Maximize}"
Grid.Column="2">
<Image Source="{xctk:ImageUri AssemblyName=Xceed.Wpf.AvalonDock, Path=Themes/Generic/Images/PinMaximize.png}">
</Image>
</Button>
<Button shell:WindowChrome.IsHitTestVisibleInChrome="True"
Focusable="False"
Visibility="{Binding IsMaximized, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BoolToVisibilityConverter}}"
Style="{DynamicResource {x:Static ToolBar.ButtonStyleKey}}"
Command="{x:Static shell:SystemCommands.RestoreWindowCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource TemplatedParent}}"
ToolTip="{x:Static avalonDockProperties:Resources.Window_Restore}"
Grid.Column="2">
<Image Source="{xctk:ImageUri AssemblyName=Xceed.Wpf.AvalonDock, Path=Themes/Generic/Images/PinRestore.png}">
</Image>
</Button>
<Button shell:WindowChrome.IsHitTestVisibleInChrome="True"
Focusable="False"
Style="{DynamicResource {x:Static ToolBar.ButtonStyleKey}}"
Command="{Binding Path=RootDocumentLayoutItem.CloseCommand, RelativeSource={RelativeSource TemplatedParent}}"
ToolTip="{x:Static avalonDockProperties:Resources.Document_Close}"
Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}"
Grid.Column="3">
<Image Source="{xctk:ImageUri AssemblyName=Xceed.Wpf.AvalonDock, Path=Themes/Generic/Images/PinClose.png}">
</Image>
</Button>
</Grid>
<ContentPresenter Content="{TemplateBinding Content}"
Grid.Row="1" />
</Grid>
</Border>
</Grid>
</AdornerDecorator>
<ControlTemplate.Triggers>
<Trigger Property="WindowState"
Value="Maximized">
<Setter Property="Padding"
Value="3"
TargetName="WindowBorder" />
</Trigger>
<DataTrigger Binding="{Binding Model.RootDocument.IsActive, RelativeSource={RelativeSource Self}}"
Value="True">
<Setter TargetName="WindowBorder"
Property="BorderBrush"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Related
I have a problem with nested template bindings.
Having an ItemsControl with a template, which works great. This template contains a tooltip as well (which shows perfectly).
<Button.ToolTip>
<TextBlock Text="{Binding Path=DetailPaneText}" />
</Button.ToolTip>
But inside the itemscontrol template, I have a ToggleButton with another template inside it. And I can't seem to show the text over there as well since the binding isn't correct.
Code inside the toggle button
<StackPanel Background="#293344" Width="200" x:Name="DetailTab" Margin="0">
<TextBlock FontSize="12" Text="" Foreground="White" />
</StackPanel>
What kind of binding or syntax should I put in between the Text tags? I tried several options but none of them seemed to work yet. Currently out of guesses.
Thanks
Complete code snippet
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0" >
<Button Command="{x:Static CobraInfrastructure:Commands.NavigateFromBreadcrumb}" CommandParameter="{Binding Path=Current}" Tag="{Binding DetailPaneText}" x:Name="TextBlock_Detail" Style="{DynamicResource BreadcrumbButton}">
<Button.Resources>
<Style BasedOn="{StaticResource {x:Type ToolTip}}" TargetType="ToolTip">
<Setter Property="Background" Value="#F8F8F8" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Padding" Value="15" />
<Setter Property="MinWidth" Value="300" />
<Setter Property="MinHeight" Value="150" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
</Button.Resources>
<Button.ToolTip>
<TextBlock Text="{Binding Path=DetailPaneText}" />
</Button.ToolTip>
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="HyphenTextBlock" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Text="{Binding Path=EntityTitle}" FontSize="12" FontWeight="Bold" Foreground="White" Grid.Row="0" Grid.Column="0"/>
<TextBlock VerticalAlignment="Stretch" Text="{Binding Path=Text, NotifyOnTargetUpdated=True, Mode=OneWay}" FontSize="10" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"/>
</Grid>
</Button>
<ToggleButton Focusable="False" Style="{DynamicResource BreadcrumbOpenButton}" VerticalAlignment="Stretch" HorizontalAlignment="Center" Tag="{Binding Path=DetailPaneText}">
<ToggleButton.Template>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<StackPanel Orientation="Horizontal">
<Border Width="13" Background="#293344">
<fa:FontAwesome Icon="CaretRight" Foreground="White" FontSize="18" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border>
<StackPanel Background="#293344" Width="200" x:Name="DetailTab" Margin="0">
<TextBlock FontSize="12" Text="" Foreground="White" />
</StackPanel>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Width" TargetName="DetailTab" Value="200"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Width" TargetName="DetailTab" Value="1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Binding="{Binding IsOverview}" Value="True">
<Setter Property="Style" TargetName="TextBlock_Detail" Value="{DynamicResource LinkButton}" />
<Setter Property="FontWeight" TargetName="TextBlock_Detail" Value="Bold" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
You should reference on TemplatedParent in Binding:
<StackPanel Background="#293344" Width="200" x:Name="DetailTab" Margin="0">
<TextBlock FontSize="12" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext.DetailPaneText}" Foreground="White" />
</StackPanel>
If you trying to bind a tooltip text of a button to the Text property of textblock, you may bind it using the ElementName.
First name your button using x:Name
<Button x:Name="XButton">
<Button.ToolTip>
<TextBlock Text="{Binding Path=DetailPaneText}" />
</Button.ToolTip>
</Button>
Bind it to text block text using the ElementName.
<StackPanel Background="#293344" Width="200" x:Name="DetailTab" Margin="0">
<TextBlock FontSize="12" Text="{Binding ElementName=XButton, Path=ToolTip.Text}" />
</StackPanel>
I have a custom datagrid whose cell is styled as below
<Style x:Key="CellStyleBase"
TargetType="{x:Type DataGridCell}">
<Setter Property="Visibility"
Value="Visible" />
<Setter Property="Background"
Value="{Binding RelativeSource={RelativeSource Self}, Path=Column.Header.CellBackground}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid x:Name="BackgroundGrid"
Background="{TemplateBinding Background}">
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Text}"
HorizontalAlignment="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Column.Header.CellHorzontalAlignment}"
VerticalAlignment="Center"
FontWeight="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Column.Header.CellFontWeight}"
Margin="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Margin}"
Padding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Padding}" />
<Grid.LayoutTransform>
<TransformGroup>
<RotateTransform Angle="-90" />
</TransformGroup>
</Grid.LayoutTransform>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The datagrid is styled as below
<Style TargetType="{x:Type local:CustomDataGrid}">
<Setter Property="BorderThickness"
Value="1" />
<!-- This is needed to force DG to have a non-default value. Otherwise the DGR.DetailsVisibility cannot have a value of VisibleWhenSelected by default. -->
<Setter Property="RowDetailsVisibilityMode"
Value="VisibleWhenSelected" />
<Setter Property="ScrollViewer.CanContentScroll"
Value="true" />
<Setter Property="VirtualizingPanel.IsVirtualizing"
Value="True" />
<Setter Property="VirtualizingPanel.VirtualizationMode"
Value="Recycling" />
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled"
Value="True" />
<Setter Property="EnableColumnVirtualization"
Value="True" />
<Setter Property="EnableRowVirtualization"
Value="True" />
<Setter Property="LayoutTransform">
<Setter.Value>
<TransformGroup>
<RotateTransform Angle="90" />
</TransformGroup>
</Setter.Value>
</Setter>
<Setter Property="CellStyle"
Value="{StaticResource CellStyleBase}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomDataGrid}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True"
Padding="{TemplateBinding Padding}">
<ScrollViewer Focusable="false"
Name="DG_ScrollViewer">
<ScrollViewer.Template>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!--Left Column Header Corner -->
<Border BorderBrush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:CustomDataGrid}}, Path=HeaderBorderBrush}"
BorderThickness="0,0,1,0"
Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:CustomDataGrid}}, Path=HeaderBackground}"
Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=CellsPanelHorizontalOffset}"
Visibility="Collapsed" />
<!--Column Headers-->
<DataGridColumnHeadersPresenter Grid.Column="1"
Name="PART_ColumnHeadersPresenter"
Visibility="Visible">
<DataGridColumnHeadersPresenter.Style>
<Style TargetType="{x:Type DataGridColumnHeadersPresenter}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeadersPresenter}">
<Border Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:CustomDataGrid}}, Path=NameHeaderBackground}">
<ItemsPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGridColumnHeadersPresenter.Style>
</DataGridColumnHeadersPresenter>
<!--Column Header Splitter-->
<GridSplitter Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Height="4"
HorizontalAlignment="Stretch"
Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:CustomDataGrid}}, Path=NameHeaderBackground}"
Foreground="Transparent"
Cursor="SizeWE" />
<!-- Line separates the column header with the content-->
<Canvas Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Height="1.5"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:CustomDataGrid}}, Path=HorizontalGridLinesBrush}" />
<!--DataGrid content-->
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
Grid.Row="2"
Grid.ColumnSpan="2"
CanContentScroll="{TemplateBinding CanContentScroll}" />
<ScrollBar Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="2"
Name="PART_VerticalScrollBar"
Orientation="Vertical"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Style="{StaticResource ScrollBarStyle}" />
<Grid Grid.Row="3"
Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=NonFrozenColumnsViewportHorizontalOffset}" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ScrollBar Grid.Column="1"
Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Style="{StaticResource ScrollBarStyle}" />
</Grid>
</Grid>
</ControlTemplate>
</ScrollViewer.Template>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger SourceName="DG_ScrollViewer"
Property="ComputedVerticalScrollBarVisibility"
Value="Visible">
<Setter Property="IsShowingHorizontalScrollBar"
Value="True" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In the datagrid, rows will be dynamically added using a background thread and it can contain thousands of data. There is a performance issue with the datagrid. CPU usage keeps on increasing.
I found out that the reason is LayoutTransform. If I set the Height of the DataGridCell or Width of the Grid which is the content of the cell, the CPU usage will be reduced. But I cannot hardcode the same. The width should be set based on the length of the content.
Setting hardcoded height:
<Setter Property="Height"
Value="50" />
Setting hardcoded width:
<Grid x:Name="BackgroundGrid"
Background="{TemplateBinding Background}"
Width="50">
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Text}"
HorizontalAlignment="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Column.Header.CellHorzontalAlignment}"
VerticalAlignment="Center"
FontWeight="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Column.Header.CellFontWeight}"
Margin="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Margin}"
Padding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Padding}" />
<Grid.LayoutTransform>
<TransformGroup>
<RotateTransform Angle="-90" />
</TransformGroup>
</Grid.LayoutTransform>
</Grid>
First, I tried binding a converter to which content is passed and width is calculated and returned to Width property of Grid. This causes a flickering while new data is added and the CPU usage will be increased.
<Grid x:Name="BackgroundGrid"
Background="{TemplateBinding Background}"
Width="{Binding Path=Content.Text,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Converter={StaticResource WidthConverter}}">
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Text}"
HorizontalAlignment="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Column.Header.CellHorzontalAlignment}"
VerticalAlignment="Center"
FontWeight="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Column.Header.CellFontWeight}"
Margin="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Margin}"
Padding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridCell}},Path=Content.Padding}" />
<Grid.LayoutTransform>
<TransformGroup>
<RotateTransform Angle="-90" />
</TransformGroup>
</Grid.LayoutTransform>
</Grid>
Second, I replaced LayoutTransform with RenderTransform. The width of the cell will not increase based on the content which will result in showing only part of the data.
Third, I tried binding a property to Height of DataGridCell which is updated dynamically with highest width of the value in the DataGridCell. This is also consuming CPU usage.
Is there any other alternative to achieve the result of LayoutTransform other than RenderTransform?
Looking forward to any kind of input/suggestions. Thanks.
I would try making the transform happen in the rendering logic itself. I haven't tried this myself but I think it is worth a shot to see if this would give similar performance to using RenderTransform while also giving you the result that you are looking for if you use RotatedText in place of your TextBlock with the LayoutTransform:
public class RotatedText : FrameworkElement
{
public string Text { get; set; }
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
var ft = new FormattedText(Text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Calibri"), 12, Brushes.Black);
drawingContext.PushTransform(new RotateTransform(-90, 0, ft.Width));
drawingContext.DrawText(ft, new Point(0, ft.Width));
drawingContext.Pop();
Width = ft.Height;
Height = ft.Width;
}
}
I have a custom datagrid which is styled as below
<Style TargetType="{x:Type local:CustomDataGrid}">
<Setter Property="BorderThickness"
Value="1" />
<!-- This is needed to force DG to have a non-default value. Otherwise the DGR.DetailsVisibility cannot have a value of VisibleWhenSelected by default. -->
<Setter Property="RowDetailsVisibilityMode"
Value="VisibleWhenSelected" />
<Setter Property="ScrollViewer.CanContentScroll"
Value="true" />
<Setter Property="VirtualizingPanel.IsVirtualizing"
Value="True" />
<Setter Property="VirtualizingPanel.VirtualizationMode"
Value="Recycling" />
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled"
Value="True" />
<Setter Property="EnableColumnVirtualization"
Value="True" />
<Setter Property="EnableRowVirtualization"
Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomDataGrid}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True"
Padding="{TemplateBinding Padding}">
<ScrollViewer Focusable="false"
Name="DG_ScrollViewer">
<ScrollViewer.Template>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!--Left Column Header Corner -->
<Border BorderBrush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:CustomDataGrid}}, Path=HeaderBorderBrush}"
BorderThickness="0,0,1,0"
Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:CustomDataGrid}}, Path=HeaderBackground}"
Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=CellsPanelHorizontalOffset}"
Visibility="Collapsed" />
<!--Column Headers-->
<DataGridColumnHeadersPresenter Grid.Column="1"
Name="PART_ColumnHeadersPresenter"
Visibility="Visible">
<DataGridColumnHeadersPresenter.Style>
<Style TargetType="{x:Type DataGridColumnHeadersPresenter}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeadersPresenter}">
<Border Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:CustomDataGrid}}, Path=NameHeaderBackground}">
<ItemsPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGridColumnHeadersPresenter.Style>
</DataGridColumnHeadersPresenter>
<!--Column Header Splitter-->
<GridSplitter Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Height="4"
HorizontalAlignment="Stretch"
Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:CustomDataGrid}}, Path=NameHeaderBackground}"
Foreground="Transparent"
Cursor="SizeWE" />
<!-- Line separates the column header with the content-->
<Canvas Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Height="1.5"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:CustomDataGrid}}, Path=HorizontalGridLinesBrush}" />
<!--DataGrid content-->
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter"
Grid.Row="2"
Grid.ColumnSpan="2"
CanContentScroll="{TemplateBinding CanContentScroll}" />
<ScrollBar Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="2"
Name="PART_VerticalScrollBar"
Orientation="Vertical"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Style="{StaticResource ScrollBarStyle}" />
<Grid Grid.Row="3"
Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=NonFrozenColumnsViewportHorizontalOffset}" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ScrollBar Grid.Column="1"
Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Style="{StaticResource ScrollBarStyle}" />
</Grid>
</Grid>
</ControlTemplate>
</ScrollViewer.Template>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<!-- The DataGrid is always rotated either +90 or -90 degrees, depending on whether the Trend Control scrolls to the left or to the right.
So, the vertical scrollbar is rendered as a horizontal scrollbar -->
<Trigger SourceName="DG_ScrollViewer"
Property="ComputedVerticalScrollBarVisibility"
Value="Visible">
<Setter Property="IsShowingHorizontalScrollBar"
Value="True" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In this datagrid, itemssource is being dynamically updated using a background thread. The number of rows are usually limited and it will not be more than 10 but the number of columns will be in thousands. Though virtualization has been enabled, it doesn't seem to be working. The column virtualization is expected to work but it is not working. The UI is not at all responsive while the datagrid is loaded.
Looking forward to any kind of input/suggestions. Thanks.
I am trying to create some kind of a window or a toolbox which can be dragged by its header part, just like any window. For some reason, it doesn't seem to work for me. The header moves but the body part stays still.
Here's my code:
BehaviorCollection behaviorCollection = Interaction.GetBehaviors(this._explorerHeader);
MouseDragElementBehavior mouseDragBehavior = new MouseDragElementBehavior { ConstrainToParentBounds = false };
mouseDragBehavior.Dragging += (s1, e1) =>
{
Canvas.SetLeft(this._explorerBody, (Double)_explorerHeader.GetValue(Canvas.LeftProperty));
Canvas.SetTop(this._explorerBody, ((Double)_explorerHeader.GetValue(Canvas.TopProperty) + _explorerHeader.ActualHeight));
};
behaviorCollection.Add(mouseDragBehavior);
UPDATE:
Here's the control template of the control:
<Style x:Key="ApplicationExplorerDefaultStyle" TargetType="Controls:ApplicationExplorer">
<Setter Property="Width" Value="150" />
<Setter Property="Height" Value="300" />
<Setter Property="CornerRadius" Value="0" />
<Setter Property="Background" Value="{StaticResource LightBlue}" />
<Setter Property="HeaderBackgroundBrush" Value="{StaticResource VeryLightBlue}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="TreeItemTemplate" Value="{StaticResource ChildTemplate}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Controls:ApplicationExplorer">
<Border BorderBrush="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BorderBrush}"
BorderThickness="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BorderThickness}"
CornerRadius="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=CornerRadius}"
Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Width}"
Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height}" >
<Grid x:Name="Root" MinWidth="100">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid x:Name="ExplorerHeader" Grid.Row="0" Background="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=HeaderBackgroundBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="40" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1" Text="{TemplateBinding Title}" Style="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TitleStyle}" VerticalAlignment="Center" />
<Controls:LayoutToggleButton Grid.Column="2" x:Name="LayoutButton" Cursor="Hand" />
</Grid>
<Border x:Name="ExplorerBody" Background="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}"
Grid.Row="1" HorizontalAlignment="Stretch" BorderThickness="0" >
<toolkit:TreeViewDragDropTarget AllowedSourceEffects="Copy" x:Name="treeViewDropTarget"
HorizontalAlignment="Left" VerticalAlignment="Top" >
<sdk:TreeView x:Name="treeView" ItemsSource="{TemplateBinding Nodes}" Background="Transparent" BorderThickness="0"
ItemTemplate="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TreeItemTemplate}"
HorizontalAlignment="Left" Margin="10 0 0 0" />
</toolkit:TreeViewDragDropTarget>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Any suggestions?
I have a little issue.
I have a a ListBox that is bound to a list of object. These Objects have a property that can be set. I have in the LIstBox ItemTemplate (a datatemplate) a combobox that is about to the objects property and the combobox has some hardcoded values.
My problem is that when the list box is displayed and I click ont he combo, only the ListBoxItem is selected, The click never makes it to the combobox!
just to give you an idea.
<ListBox SelectionMode="Multiple" VerticalAlignment="Center" HorizontalAlignment="Left" Style="{StaticResource Style_ListBox}" ItemsSource="{Binding ModeSampleSets, Mode=OneWay}">
<ListBox.ItemTemplate>
<DataTemplate DataType="ListBoxItem">
<Grid>
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" FontWeight="Bold" Text="{Binding Name, Mode=OneWay}" Width="{Binding ElementName=this, Path=Content.DesiredWidth}"/>
<ComboBox Focusable="False" Width="10" Height="10" Grid.Column="2" Style="{StaticResource Style_ComboBoxColorPicker}" SelectedItem="{Binding GraphColor, Mode=TwoWay}" >
<ComboBoxItem IsSelected="True" Content="#e62a2c" />
<ComboBoxItem Content="#ec7c28"></ComboBoxItem>
<ComboBoxItem Content="#69c5d8"></ComboBoxItem>
<ComboBoxItem Content="#36b34b"></ComboBoxItem>
<ComboBoxItem Content="#415dae"></ComboBoxItem>
<ComboBoxItem Content="#9056A3"></ComboBoxItem>
<ComboBoxItem Content="#0b0b0b"></ComboBoxItem>
<ComboBoxItem Content="#666666"></ComboBoxItem>
<ComboBoxItem Content="#a6a6a6"></ComboBoxItem>
</ComboBox>
</Grid>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="8" Text="{Binding SampleAnalysisDate, Mode=OneWay}" Width="{Binding ElementName=this, Path=Content.DesiredWidth}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,4,0,0">
<TextBlock FontSize="14" Text="{Binding WaveLengthStart, Mode=OneWay}" Width="{Binding ElementName=this, Path=Content.DesiredWidth}"/>
<TextBlock Margin="2,0,0,0" FontSize="14" Text="{x:Static UIStrings:WaveLengthScanStrings.WaveLengthScanModeView_SampleWaveLength_Seperator}" Width="{Binding ElementName=this, Path=Content.DesiredWidth}"/>
<TextBlock Margin="2,0,0,0" FontSize="14" Text="{Binding WaveLengthStop, Mode=OneWay}" Width="{Binding ElementName=this, Path=Content.DesiredWidth}"/>
</StackPanel>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Styles:
<Style x:Key="Style_ComboBoxColorPickerItemContainerStyle" TargetType="ComboBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBoxItem">
<Border Name="ItemBorder" Margin="2" BorderBrush="Transparent" BorderThickness="1.5" Background="Transparent">
<ContentPresenter Margin="2" Height="20" Width="20" ContentTemplate="{StaticResource DataTemplate_ComboBoxColorPickerItemTemplate}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="ItemBorder" Property="BorderBrush" Value="Black"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="Style_ComboBoxColorPicker" TargetType="ComboBox">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel MaxWidth="100"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate" Value="{StaticResource DataTemplate_ComboBoxColorPickerItemTemplate}"/>
<Setter Property="ItemContainerStyle" Value="{StaticResource Style_ComboBoxColorPickerItemContainerStyle}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton
ClickMode="Press"
Name="ComboToggleButton"
IsChecked="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
Focusable="False"
>
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<ContentPresenter/>
</ControlTemplate>
</ToggleButton.Template>
<ContentPresenter Content="{TemplateBinding ComboBox.SelectionBoxItem}" ContentTemplate="{TemplateBinding ComboBox.ItemTemplate}" ContentTemplateSelector="{TemplateBinding ComboBox.ItemTemplateSelector}"/>
</ToggleButton>
<Popup
Placement="Bottom"
Name="Popup"
Focusable="False"
AllowsTransparency="True"
IsOpen="{TemplateBinding ComboBox.IsDropDownOpen}"
PopupAnimation="Fade">
<Grid
MinWidth="{TemplateBinding FrameworkElement.ActualWidth}"
MaxHeight="{TemplateBinding ComboBox.MaxDropDownHeight}"
Name="DropDown"
SnapsToDevicePixels="True">
<Border
BorderBrush="Gray"
BorderThickness="1.5"
Name="DropDownBorder"
Background="White">
<ScrollViewer
Margin="0"
SnapsToDevicePixels="True">
<ItemsPresenter />
</ScrollViewer>
</Border>
</Grid>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="Style_ListBox" TargetType="ListBox">
<Setter Property="BorderBrush" Value="{StaticResource Brush_PanelInnerBorder}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Background="{StaticResource Brush_PanelInnerBackground}"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid Background="{StaticResource Brush_PanelInnerBackground}" Margin="-.5">
<Border x:Name="BorderItem" Margin="0" ClipToBounds="True" BorderThickness="0" Style="{StaticResource Style_PanelInnerBorder}">
<Rectangle x:Name="BackgroundRec" Fill="Transparent" Stroke="Transparent" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Border>
<ContentPresenter Name="TheContentPresenter" Margin="5" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Border Margin="0" ClipToBounds="True" Style="{StaticResource Style_PanelInnerBorder}">
<Rectangle VerticalAlignment="Bottom" Width="{TemplateBinding Width}" Height="0"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="BorderItem" Property="Background" Value="{StaticResource Brush_Highlight}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
Make sure you don't have IsHitTestVisible="False" on the ComboBox's style. Can you please post here the styles you're using?
I found the problem.
My ItemContainerStyle Template had a rectangle and i guess it was implying zindex somehow. When I expclicity told it to draw the content before the border and it's rectangle, it worked. i just had to add Panel.ZIndex="1" and it worked.