I've this code with TabItems added Dynamycally in CodeBehind (C#):
<TabControl x:Name="tabList" Grid.Column="2" HorizontalContentAlignment="Stretch" Background="Transparent" SelectionChanged="tabList_SelectionChanged" IsSynchronizedWithCurrentItem="True">
<TabControl.Resources>
<DataTemplate x:Key="TabHeader" DataType="TabItem">
<DockPanel>
<Button x:Name="btnDelete" BorderThickness="0" Background="Transparent" DockPanel.Dock="Right" Margin="5,0,0,0" Padding="0" Click="btnDelete_Click" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Name}">
<Image Source="myImage></Image>
</Button>
<ToggleButton x:Name="btnPin" Checked="btnDisablex" Unchecked="btnDisablex" BorderThickness="0" Background="Transparent" DockPanel.Dock="Right" Margin="5,0,0,0" Padding="0" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Name}">
<ToggleButton.Style>
//Many Useless Things
</ToggleButton.Style>
</ToggleButton>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Header}" />
</DockPanel>
</DataTemplate>
<Style TargetType="TextBox">
//Other Many Useless Things
</Style>
</TabControl.Resources>
</TabControl>
And with the following Style in User Resources:
<Style TargetType="{x:Type TabItem}">
<Setter Property="AllowDrop" Value="True"/>
<EventSetter Event="PreviewMouseMove" Handler="TabItem_PreviewMouseMove"/>
<EventSetter Event="Drop" Handler="TabItem_Drop"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border
Name="Border"
Margin="0,0,-4,0"
Background="White"
BorderBrush="#888"
BorderThickness="1,1,1,1"
CornerRadius="2,12,0,0">
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="12,2,12,2"
RecognizesAccessKey="True"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
//Many Useless MultiTrigger and Datatrigger
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The code is working fine, until I add more tabs and the window width is no longer enough, but the TabControl behaviour is strange: the TabItem width becomes larger and the first TabItems disappear.
I just want the TabItem width reduces or just that the olders "disappear" but keeping always the same width. Why this is not working?
This is the screenshot taken in normal conditions
Normal view working OK
Here it's clear the problem: when I add more tabs (or I reduce the window/grid width) the tab width becomes larger
Tab View Problem
Related
I'm developing a CheckedListBox with self removable ListBoxItems. The problem is that an item only gets checked if the user clicks on the CheckBox area, which is kind of awkward.
How do I create ListBoxItem triggers (IsSelected) to check the checkboxes on a "DataSourced" ListBox? Eg:
Below is my control (all other code have been omitted for brevity):
<ListBox x:Name="executors" ItemsSource="{Binding Executors}" HorizontalAlignment="Left" Height="121" Margin="23,19,0,0" VerticalAlignment="Top" Width="362">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Height" Value="30" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<CheckBox Margin="4,8" IsChecked="{Binding Enabled}">
<ContentPresenter Content="{Binding Description}">
</ContentPresenter>
</CheckBox>
<Button Command="{Binding DataContext.RemoveExecutorCommand, ElementName=executors}" CommandParameter="{Binding}" Background="White" Height="22" Width="22" Grid.Column="1">
<Image Source="trash.png" Stretch="Fill" Width="14" Height="14" />
</Button>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Executors is a ObservableCollection of Executor which has Enabled and Description as members.
For further reference for those who come across this same question, here's a working snippet I have done. I couldn't find any working sample anywhere, so this might be of much use.
The main idea here was to either propagate the selection event to the CheckBoxes, which sounds too much of a work, or to simple extend the CheckBox selection area to fit the ListBoxItem.
Below is a sample on how to achieve the second option:
<ListBox x:Name="executors" ItemsSource="{Binding Executors}" HorizontalAlignment="Left" Height="121" Margin="23,19,0,0" VerticalAlignment="Top" Width="362" ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Height" Value="30"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="9*"/>
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<CheckBox Content="{Binding Description}" IsChecked="{Binding Enabled}" VerticalContentAlignment="Center" Margin="4,0"/>
<Button Command="{Binding DataContext.RemoveExecutorCommand, ElementName=executors}" CommandParameter="{Binding}" Width="21" Height="21" Background="White" Grid.Column="1">
<Image Source="trash.png" Stretch="Fill" Width="14" Height="14" />
</Button>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
This should produce the following:
I am wanting to just set the title bar and border of a WPF window but the title background property doesn't look to be exposed in the class.
I want to leave all default Window behavior and just set the color property of Title Bar and Border
What is the correct property to set?
I am refrencing: https://learn.microsoft.com/en-us/dotnet/api/system.windows.shell.windowchrome?view=netframework-4.7.2
<ResourceDictionary>
<Style x:Key="CustomWindowStyle" TargetType="{x:Type Window}">
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome/>
</Setter.Value>
</Setter>
<Setter Property="??" Value="Blue"/>
</Style>
</ResourceDictionary>
The only property I see is the Title Property and setting its color has no effect
So I resolved this and it was more involved then I had originally thought. Since the title bar is in the non-client area when editing it I would lose the visibility of the corner buttons.
In the end I had to reconstruct the title bar and create a class to implement the buttons to get the look I desired.
This will give you a window with a border and the title bar will also have a color. You need to implement the corner buttons though.
xmlns:shell="http://schemas.microsoft.com/netfx/2009/xaml/presentation"
<Style x:Key="StandardStyle" TargetType="{x:Type Window}">
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome
/>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}" >
<Grid>
<!--Title Panel-->
<DockPanel LastChildFill="True">
<Border Background="Blue" DockPanel.Dock="Top"
Height="{x:Static SystemParameters.CaptionHeight}" x:Name="titlebar">
<Grid>
<!--Title text only-->
<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title}"
VerticalAlignment="Top" HorizontalAlignment="Center" Background="Transparent" />
<usercontrols:CornerButtons HorizontalAlignment="Right"/>
</Grid>
</Border>
<!--Provides the actual content control-->
<Border Margin="0,0,0,0" >
<AdornerDecorator>
<ContentPresenter Content="{TemplateBinding Content}"/>
</AdornerDecorator>
</Border>
</DockPanel>
<!--Provides the actual window border-->
<Border
Margin="0,0,0,0"
Background="White"
Grid.ZIndex="-1"
BorderThickness="2,2,2,2" BorderBrush="Blue"
>
</Border>
<!--This is the top left system button-->
<!--<Button
Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(shell:WindowChrome.WindowChrome).ResizeBorderThickness}"
Padding="1"
HorizontalAlignment="Left"
VerticalAlignment="Top"
shell:WindowChrome.IsHitTestVisibleInChrome="True"
Command="{x:Static shell:SystemCommands.ShowSystemMenuCommand}"
CommandParameter="{Binding ElementName=CalcWindow}">
<Image
Width="16"
Height="16"
shell:WindowChrome.IsHitTestVisibleInChrome="True"
Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Icon}" />
</Button>-->
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I'm currently trying to apply styling to my menuItem. I had to center it's header inside the control, and the only way to it that I had found is this:
<MenuItem>
<MenuItem.Header>
<TextBlock Text="About" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</MenuItem.Header>
</MenuItem>
Now, I am trying to apply styles, but I can't seem to manage to bind the textboxes' text from style to the actual xaml value.
My style:
<Style x:Key="MenuItemBaseStyle" TargetType="MenuItem">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="#0a99f3" />
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Grid Background="{TemplateBinding Background}">
<MenuItem>
<MenuItem.Header>
<TextBlock Text="{TemplateBinding Text}" />
</MenuItem.Header>
</MenuItem>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
TemplateBinding is just one of the approaches I tried, though none worked even remotely close.
EDIT - FULL XAML ON REQUEST:
<Window x:Class="DownloadManager.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:local="clr-namespace:DownloadManager"
xmlns:controls="clr-namespace:DesignInControl"
mc:Ignorable="d"
Title="MainWindow" Height="700" Width="1000" Background="#22282a" ResizeMode="NoResize">
<Border BorderThickness="1" BorderBrush="#ffcd22" Margin="10,10,10,10">
<Grid>
<controls:CircularProgressBar VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0,0,10,10" SegmentColor="#ffcd22" StrokeThickness="5" Percentage="100" Radius="80" Grid.ZIndex="0"/>
<Border VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0,0,10,10" Width="170" Height="170">
<TextBlock FontSize="60" Text="10%" FontFamily="simplifica" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<Image x:Name="noshare_png" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="-8,10" Source="noshare.png" Width="100" Height="100"/>
<Border Width="210" Height="100" Margin="97,10,665,540">
<TextBlock Text="NoShare" FontSize="85" FontFamily="simplifica" Foreground="#ffcd22" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<Menu x:Name="menu" HorizontalAlignment="Left" Height="100" Margin="352,10,0,0" VerticalAlignment="Top" Width="600" FontFamily="simplifica" FontSize="30">
<MenuItem Height="100" Width="200" Style="{StaticResource MenuItemBaseStyle}">
<MenuItem.Header>
<TextBlock Text="File"/>
</MenuItem.Header>
</MenuItem>
<MenuItem Height="100" Width="200" Style="{StaticResource MenuItemBaseStyle}">
<MenuItem.Header>
<TextBlock Text="Settings"/>
</MenuItem.Header>
</MenuItem>
<MenuItem Height="100" Width="200" Style="{StaticResource MenuItemBaseStyle}">
<MenuItem.Header>
<TextBlock Text="About"/>
</MenuItem.Header>
</MenuItem>
</Menu>
</Grid>
</Border>
</Window>
Use MenuItem.HeaderTemplate.
<Style x:Key="MenuItemBaseStyle" TargetType="MenuItem">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="#0a99f3" />
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
Updated: Combined your style with the original solution.
I got a TabControl with two TabItems, I created a template for it.
<TabControl x:Name="MainInfoTabControl" Grid.Row="3" Grid.RowSpan="7" Grid.Column="0" Grid.ColumnSpan="2"
Background="{x:Null}"
BorderBrush="{x:Null}"
>
<TabControl.Resources>
<Style x:Key="TabHeaderStyle" TargetType="{x:Type TabItem}">
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="FontWeight" Value="DemiBold" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Border x:Name="HeaderBorder" BorderBrush="White" BorderThickness="2" CornerRadius="10,10,0,0" >
<TextBlock Text="" VerticalAlignment="Center" Margin="5"></TextBlock>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<TabItem Header="Main Details"
Margin="0.5, 0.5, 0, 0.5"
FontSize="15"
MinHeight="40" Width="200"
Style="{StaticResource TabHeaderStyle}"
>
</TabItem>
<TabItem Header="Pets Owned"
Margin="0.5, 0.5, 0, 0.5"
FontSize="15"
MinHeight="40" Width="200"
Style="{StaticResource TabHeaderStyle}"
>
</TabItem>
</TabControl>
The problem is the tabItem's Header doesn't show up. In my template there is a TextBlock but i couldn't customize the TextBlock.Text dynamically (atleast bind or somewhat change the Text property during run time)
TabItem1 should be "Owner Details" while TabItem2 should be "Pets Owned"
You override default tabitem template you need to get somehow to parent's value.
<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Header}"
VerticalAlignment="Center"
Margin="5">
</TextBlock>
or
<TextBlock Text="{TemplateBinding Property=Header}"
VerticalAlignment="Center"
Margin="5">
</TextBlock>
I am working on a C# WPF project and I have a list view which uses data binding and a collection view.
Below is how my ListView is currently populated.
<ListView HorizontalAlignment="Left" Margin="547,12,0,41" Name="lstCallLogInformation" Width="320">
<ListView.Style>
<Style TargetType="ListView">
<Style.Triggers>
<Trigger Property="HasItems" Value="False">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListView">
<TextBlock Text="No items in your devices call log" FontWeight="Bold" HorizontalAlignment="Center" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ListView.Style>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock FontWeight="Bold" Foreground="Gray" Text="{Binding Name}" VerticalAlignment="Bottom" />
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Control.HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel Style="{StaticResource onmouseover}">
<StackPanel HorizontalAlignment="Stretch" Orientation="Horizontal" Tag="{Binding logID}">
<Image Height="30" Source="{Binding base64ImageString, Converter={StaticResource ImageConverter}}" Width="30" />
<StackPanel Margin="10" Orientation="Vertical">
<TextBlock FontWeight="Bold" Text="{Binding contactNameOrPhoneNumber}" />
<StackPanel HorizontalAlignment="Stretch" Orientation="Horizontal">
<TextBlock HorizontalAlignment="Left" Text="{Binding dateString}" />
<TextBlock Margin="15, 0, 0, 0" Text="Duration: " />
<TextBlock HorizontalAlignment="Right" Text="{Binding humanReadableCallDuration}" />
</StackPanel>
</StackPanel>
<StackPanel Orientation="Vertical">
<Button Background="Transparent" BorderThickness="0" BorderBrush="Transparent" Tag="{Binding logID}" Name="btnAddAsContact" Click="btnAddAsContact_Click">
<Image Width="15" Height="15" Source="/BoardiesSMSServer;component/images/add.png" Tag="{Binding logID}" />
</Button>
<Button Background="Transparent" BorderThickness="0" BorderBrush="Transparent" Tag="{Binding logID}" Name="btnDeleteContactFromLog" Click="btnDeleteContactFromLog_Click">
<Image Width="15" Height="15" Source="/BoardiesSMSServer;component/images/delete.png" Margin="0,0,0,5" Tag="{Binding logID}" />
</Button>
</StackPanel>
</StackPanel>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Within my DockPanel within the DataTemplate I have a StackPanel which contains various TextBlocks from the array that is passed into the binding.
In one of the StackPanels you will see you will see a TextBlock that binds to the element of contactNameOrPhoneNumber.
What I want to be able to do is if another value from the binding is null then I add a TextBlock for the contactNameOrPhoneNumber` element and alongside it have another TextBlock which contains another element of number``, if the other binding value is not null then this extra textblock of number is not added.
So in simple terms, what I want to be able to do is within the DataTemplate have a conditional if statement of if binding value == null add textblock to stackpanel else don't add textblock.
You can do that with Style + Triggers something like this:
<TextBlock>
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding PropertyName}" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
Also you can create IValueConverter say ObjectToVisibilityConverter which will take input your property and if property is null return Visibility.Collapsed else return Visibility.Visible.
You can then bind property with Visibility value of TextBlock via Converter.
<TextBlock Visibility="{Binding PropertyName,
Converter={StaticResource ObjectToVisibilityConverter}}"/>