Mahapps TabControl, can't set CloseButtonEnabled = true when using ItemSource ={Binding..} - c#

I am using MahApps TabControl. If I add Items from xaml I can set "CloseButtonEnabled =true" and the Close button is showed, when I try to bind ItemSource, the close button does not appear. Any ideas, how I could solve this problem?
Here is my sample code:
<Window.Resources>
<Style BasedOn="{StaticResource MetroTabItem}" TargetType="{x:Type Controls:MetroTabItem}">
<Setter Property="Controls:ControlsHelper.HeaderFontSize" Value="15"/>
<Setter Property="Foreground" Value="Red"/>
<Setter Property="CloseButtonEnabled" Value="True"/>
</Style>
</Window.Resources>
<Controls:MetroTabControl ItemsSource="{Binding AvailableFiles}" SelectedIndex="{Binding SelectedIndex}" Grid.Row="1" >
<Controls:MetroTabControl.ItemTemplate >
<DataTemplate>
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</Controls:MetroTabControl.ItemTemplate>
</Controls:MetroTabControl>

The problem here is that you override the complete style for the MetroTabItem.
If you only want additional changes then do this
<Window.Resources>
<Style BasedOn="{StaticResource {x:Type Controls:MetroTabItem}}" TargetType="{x:Type Controls:MetroTabItem}">
<Setter Property="Controls:ControlsHelper.HeaderFontSize" Value="15"/>
<Setter Property="Foreground" Value="Red"/>
<Setter Property="CloseButtonEnabled" Value="True"/>
</Style>
</Window.Resources>
The MetroTabItem in BasedOn="{StaticResource MetroTabItem}" is a style and not the type.
Hope that helps!

You can try following approach:
<Window.Resources>
<Style x:Key="MyCustomTabItem" BasedOn="{StaticResource MetroTabItem}" TargetType="{x:Type Controls:MetroTabItem}">
<Setter Property="Controls:ControlsHelper.HeaderFontSize" Value="15"/>
<Setter Property="Foreground" Value="Red"/>
<Setter Property="CloseButtonEnabled" Value="True"/>
</Style>
</Window.Resources>
<Controls:MetroTabControl ItemsSource="{Binding AvailableFiles}" ItemContainerStyle="{StaticResource MyCustomTabItem}" SelectedIndex="{Binding SelectedIndex}" Grid.Row="1" >
<Controls:MetroTabControl.ItemTemplate >
<DataTemplate>
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</Controls:MetroTabControl.ItemTemplate>
</Controls:MetroTabControl>

Related

contextmenu won't open anymore on datagrid after several updates

I have a wpf datagrid, by a template I create a contextmenu for every row.
Since the grid rows are getting constantly changed it often happens that the contextmenu gets closed when the focused row disappears.
After a while the contextmenu won't open anymore on the entire grid. It happens if the contextmenu is heavily used and there are lots of updates.
I tried to debug this by logging the ContextMenuOpening, contextMenuClosing and MouseRightButtonDown events. The "opening" gets raised but the menu isn't visible. Reopening the window clears the issue.
Currently I am at odds. Can somebody give me some pointers on how to resolve this issue?
Perhaps somebody could recommend some XAML optimization.
In the .cs file there is no interaction with the contextmenu, just adding and removing of the rows and some view-refresh (to update the grouping). The events are just for logging.
The ressource part
<Window.Resources>
<local:NegativeColorConverter x:Key="NegativeColorConverter"/>
<local:AllJobs x:Key="jobs"/>
<CollectionViewSource x:Name="cvsAllJobs" x:Key="cvsJobs" Source="{StaticResource jobs}" IsLiveGroupingRequested="True" IsLiveSortingRequested="True" CollectionViewType="ListCollectionView">
<CollectionViewSource.LiveGroupingProperties>
<s:String>omitted</s:String>
</CollectionViewSource.LiveGroupingProperties>
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="omitted"/>
</CollectionViewSource.GroupDescriptions>
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="GroupSort"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</Window.Resources>
And the grid
<DataGrid
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
x:Name="gridJobs"
CanUserSortColumns="False"
IsReadOnly="True"
CanUserDeleteRows="False"
CanUserAddRows="False"
GridLinesVisibility="Horizontal"
DragEnter="gridJobs_DragEnter"
Drop="gridJobs_Drop"
AllowDrop="True"
AutoGenerateColumns="False"
Margin="10"
SelectedItem ="{Binding SelectedRow, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Source={StaticResource cvsJobs}}"
HorizontalGridLinesBrush="Transparent"
PreviewKeyDown="gridJobs_PreviewKeyDown"
ContextMenuClosing="gridJobs_ContextMenuClosing"
ContextMenuOpening="gridJobs_ContextMenuOpening"
MouseRightButtonDown="gridJobs_MouseRightButtonDown"
>
<DataGrid.Resources>
<tools:BindingProxy x:Key="proxy" Data="{Binding}" />
<ContextMenu StaysOpen="True" x:Key="Jobs" ItemsSource="{Binding MenuItems}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Command" Value="{Binding Command}" />
<Setter Property="IsEnabled" Value="{Binding Enabled}" />
</Style>
</ContextMenu.ItemContainerStyle>
<ContextMenu.ItemTemplate>
<HierarchicalDataTemplate DataType="MenuItemViewModel" ItemsSource="{Binding MenuItems}">
<TextBlock Text="{Binding Header}"/>
</HierarchicalDataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</DataGrid.Resources>
Columns omitted
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontFamily" Value="Calibri"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<!--<Setter Property="Background" Value="Black"/>-->
<Setter Property="Background" Value="{Binding BrushState, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource NegativeColorConverter}}"/>
<Setter Property="Foreground" Value="{Binding BrushState, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow" >
<Setter Property="ContextMenu" Value="{StaticResource Jobs}" />
<Setter Property="Foreground" Value="{Binding BrushState, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
<Setter Property="Margin" Value="10,0,0,0"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Height" Value="20"/>
<Setter Property="BorderThickness" Value="0"/>
</Style>
</DataGrid.RowStyle>
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<DockPanel Background="Gray" Height="1">
</DockPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</DataGrid.GroupStyle>
</DataGrid>
Add to the ContextMenu tag an attribute x:Shared="false", this will create an own ContextMenu for each row. So it should work I think.
<ContextMenu StaysOpen="True" x:Key="Jobs" ItemsSource="{Binding MenuItems}" x:Shared="false">

WPF TextBox selected text does not work

I have a readonly TextBox control with a static resource, looks like this:
<Style TargetType="TextBox" x:Key="MyEditTextEditor">
<Setter Property="FontFamily" Value="{Binding Path=TextEditorFontFamily, ElementName=LogViewerProperty}" />
<Setter Property="FontWeight" Value="{Binding Path=TextEditorFontWeight, ElementName=LogViewerProperty}" />
<Setter Property="FontSize" Value="{Binding Path=TextEditorFontSize, ElementName=LogViewerProperty}" />
<Setter Property="FontStyle" Value="{Binding Path=TextEditorFontStyle, ElementName=LogViewerProperty}" />
<Setter Property="TextWrapping" Value="{Binding Path=WordWrapping, ElementName=LogViewerProperty, Converter={StaticResource BoolToTextWrap}}" />
<Setter Property="Text" Value="{Binding Message, Mode=OneWay}" />
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="Visibility" Value="Collapsed" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<TextBox Text="{TemplateBinding Text}" BorderThickness="0" Margin="-3,-1"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Opacity="0.4" Color="{Binding Source={x:Reference LogViewerProperty}, Path=TextEditorSelectionColor}" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
It's embedded into a ListBox. All works fine, but when I want to get the selected text, the property is always string.Empty. The SelectionChanged event works perfect. Any suggestions? At the moment I do not know, why the SelectedText is string.Empty.
Here is the SelectionChanged event
private void ReadOnlyEditor_SelectionChanged(object sender, RoutedEventArgs e)
{
LOG.Debug("Current text {3}; selection {0} length {1}, start {2}", readOnlyEditor.SelectedText, readOnlyEditor.SelectionLength, readOnlyEditor.SelectionStart, readOnlyEditor.Text);
}
And yes, the text is selected in the control, but the property is empty. In readOnlyEditor.Text exists the right text.
Put your data binding into the ListBoxItem, then call the data from the ListBoxItem. Then the whole ListBoxItem is selectable. e.g.
<ListBox SelectionChanged="ListItemSelected" ItemTemplate="{StaticResource SelectedTextTemplate}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
.../...
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Build your data template or control template outside of the ListBox e.g.
<DataTemplate x:Key="SelectedTextTemplate">
<TextBox Text="{Binding SelectedText}"/>
</DataTemplate>

wpf datagrid - how to remove black selected border?

I need help,
when I click at datagrid at cell, I want to select all line like in image (please look at image), but without black border. how to disable, or change color to transparent? I tried this:
<DataGrid.Resources>
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
</Style>
</DataGrid.Resources>
but don't work. nothing changes.
You need to style the selected cell not just cells. To do so you need to write this inside your style tag:
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderThickness" Value="0"/>
</Trigger>
</Style.Triggers>
All you need was using Triggers hope it will work for you. Also you can change background for selected cell or whatever property you want.
Following example to customize wpf datagrid (border, cell corners, etc.). You can modify it as you wish.
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style x:Key="cellStyle" TargetType="DataGridCell">
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="2" />
<Setter Property="Background" Value="Black" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridCell">
<Border Background="Black" BorderThickness="0">
<Border x:Name="border"
BorderBrush="White"
BorderThickness="2"
Background="Black"
CornerRadius="5">
<ContentPresenter />
</Border>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="true">
<Setter TargetName="border" Property="Background" Value="Orange"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="rowStyle" TargetType="DataGridRow">
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="0" />
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="Black" />
</Style>
<Grid>
<DataGrid HeadersVisibility="None" GridLinesVisibility="None" SelectionMode="Single" SelectionUnit="Cell" IsReadOnly="true"
RowStyle="{StaticResource rowStyle}" CellStyle="{StaticResource cellStyle}"
Background="Black" Foreground="White" ItemsSource="{Binding MyData}" />
</Grid>
</Page>

WPF Combobox: Only the first item should be editable

Only the first item in Combobox (selectedIndex = 0) should be editable. I have got it already. But the problem is that the selected text didn't get highlighted.
Any help would be appreciated!
Code
<Window.Resources>
<Style x:Key="ComboBoxStyle" TargetType="{x:Type ComboBox}">
<Setter Property="IsEnabled" Value="True"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=SelectedIndex, ElementName=comboBox1}" Value="0">
<Setter Property="ComboBox.IsEditable" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="FirstItem" TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<Trigger Property="ComboBox.AlternationIndex" Value="0" >
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="FontStyle" Value="Italic"/>
<Setter Property="FontFamily" Value="SEGOEWP"/>
<Setter Property="FontSize" Value="15"/>
<Setter Property="Foreground" Value="Gray"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="TextBlock.TextTrimming" Value="WordEllipsis"/>
</Trigger>
</Style.Triggers>
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Green"/>
</Style.Resources>
</Style>
</Window.Resources>
<StackPanel >
<ComboBox Name="comboBox1" Style="{StaticResource ComboBoxStyle}" Width="100" Height="38"
AlternationCount="500" ItemsSource="{Binding Items}"
ItemContainerStyle="{StaticResource FirstItem}"
SelectedItem="{Binding SelectedItem}"
SelectedIndex="{Binding SelectedIndex}"
IsTextSearchEnabled="false"
Text="{Binding NewItem, UpdateSourceTrigger=LostFocus}">
<ComboBox.InputBindings>
<KeyBinding Command="{Binding LoginCMD}" Key="Return" />
</ComboBox.InputBindings>
</ComboBox>
</StackPanel>

How To Style ListBoxItem

<Border Grid.Row="1" Padding="15" Margin="15" BorderBrush="LightBlue" Background="AliceBlue" BorderThickness="1">
<ListBox ItemsSource="{Binding Configs}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Focusable" Value="False" />
<Setter Property="BorderThickness" Value="0" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<view:Config />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
This is the code I've written in XAML. However, it doesn't appear to affect anything.
There are so many posts on SO with similar questions but all of their response are "use ListBox.ItemContainerStyle" which I've done :S Such as There is no ListBox.SelectionMode="None", is there another way to disable selection in a listbox? and WPF, XAML: How to style a ListBoxItem using binding on property of ListBox ItemsSource object?
What I would expect is that there is no background, no border and the item is not focusable.
What have I done wrong?
Redefine the ControlTemplate of your ListBoxItem. The sample code below uses a redish color just to make the point, but you can just replace it with Transparent:
<Window x:Class="WpfApplication235.MainWindow"
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"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:WpfApplication235"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<x:Array x:Key="SampleData" Type="{x:Type sys:String}">
<sys:String>Item 1</sys:String>
<sys:String>Item 2</sys:String>
<sys:String>Item 3</sys:String>
<sys:String>Item 4</sys:String>
<sys:String>Item 5</sys:String>
</x:Array>
<Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<TextBlock Text="{Binding}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#1FFF0000"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<ListBox x:Name="listBox" ItemsSource="{StaticResource SampleData}"
ItemContainerStyle="{StaticResource ListBoxItemStyle1}"
Height="150" Margin="0" Width="250"/>
</Grid>
and using a Transparent background, no focus, no highlighting, as required:
You can use style in resource like:
<Window.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="#D8D8D8"/>
<Setter Property="FontSize" Value="15"/>
<Setter Property="FontWeight" Value="400"/>
<Setter Property="Height" Value="30"/>
<!--and so on whatever you want...-->
</Style>
</Window.Resources>
And remove code like:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Focusable" Value="False" />
<Setter Property="BorderThickness" Value="0" />
</Style>
</ListBox.ItemContainerStyle>
And don't use any property in listBox which is used in style, other wise it will not behave which is described in style.

Categories