WPF trigger from a different control - c#

I'm trying to change the containing border background color based on the focus property of a contained textbox. Can someone explain what's the problem with my code?
<Border BorderBrush="LightBlue" BorderThickness="2" Background="#33000000">
<Border.Style>
<Style>
<Style.Triggers>
<DataTrigger
Binding="{Binding IsFocused, ElementName=txtValue}"
Value="True">
<Setter Property="Border.Background" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid Margin="0" VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBox Name="txtValue" Grid.Column="0" Text="20" />
<TextBlock Grid.Column="1" />
</Grid>
</Border>

Your DataTrigger is not change the value of the Background property because you set it inside the Border declaration. So, once setted, it will never changed. To allow changing, you have to set the value inside the Style.
<Border BorderBrush="LightBlue" BorderThickness="2" >
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="#33000000"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsFocused, ElementName=txtValue}" Value="True">
<Setter Property="Background" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid Margin="0" VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBox Name="txtValue" Grid.Column="0" Text="20" />
<TextBlock Grid.Column="1" />
</Grid>
</Border>

Related

WPF How to bind data between user control and mainview?

I'm trying to transfer list from mainview to user control. My solution doesn't work. Everything works fine except for the transferring the list.
My user control:
public List<Song> ListIWantTransferFromMainviewToUsercontrol = new List<Song>();
public View_Playlist()
{
InitializeComponent();
ToPlayList.ItemsSource = ListIWantTransferFromMainviewToUsercontrol;
ToPlayList.Items.Refresh();
}
My mainview:
var i = Playlists_ListBox.Items.IndexOf(Playlists_ListBox.SelectedItem);
string y = Playlists[i].Title;
var z = Playlists[i].Songs;
View_Playlist view_Playlist = new View_Playlist
{
ListIWantTransferFromMainviewToUsercontrol = z
};
this.contentControl.Content = view_Playlist;
I should click on item in listbox shown by mainview and run this code on click. Has anyone working solution for my problem? Thanks for reply.
User control XAML, listbox part:
<ListBox Name="ToPlayList" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="4" Background="{x:Null}" >
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="BorderBrush" Value="BlanchedAlmond" />
<Setter Property="BorderThickness" Value="0" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Gray" />
<Setter Property="BorderThickness" Value="2" />
</Trigger>
<Trigger Property="IsMouseCaptured" Value="True">
<Setter Property="BorderThickness" Value="2" />
<Setter Property="Background" Value="Gray" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0,2" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="205"/>
<ColumnDefinition Width="90" />
<ColumnDefinition Width="90" />
<ColumnDefinition Width="35" />
</Grid.ColumnDefinitions>
<CheckBox/>
<TextBlock Grid.Column="1" Text="{Binding SongTitle}" Foreground="White"/>
<TextBlock Grid.Column="2" Text="{Binding SongArtist}" Foreground="White"/>
<TextBlock Grid.Column="3" Text="{Binding SongDate}" Foreground="White"/>
<TextBlock Grid.Column="4" Text="{Binding Duration}" Foreground="White"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I solved it by parameter. It isn't ideal, but working.

WPF - Formatting a ComboBox's displayed item

I've formatted a ComboBox to display each item's details, please don't take the design as final, it's just an example:
But as you can see, the displayed item (Inside the box with the arrow) is broken:
So I need to format that component too, to display only the Server value in that box. I've tried to find the correct element, and even managed to find a way to reformat the whole combo box, but no way to add a template for the data display inside that box.
How do I edit the data template for that container? This is the result I'd expect:
<ComboBox x:Name="cboSourceMySql" Grid.Column="1" Margin="5,0,5,0" ItemsSource="{Binding OdbcDataSources, Mode=TwoWay}" Grid.Row="1" >
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Label Content="Server:" Grid.Column="0" Grid.Row="0" />
<TextBlock Text="{Binding Server}" VerticalAlignment="Center" Grid.Column="1" Grid.Row="0" />
<Label Content="Driver:" Grid.Column="0" Grid.Row="1" />
<TextBlock Text="{Binding Driver}" VerticalAlignment="Center" Grid.Column="1" Grid.Row="1" />
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
From the article WPF Combobox: Different template in textbox and drop-downlist
I think you can use the below style
<ComboBox
x:Name="cboSourceMySql"
Grid.Column="1" Margin="5,0,5,0"
ItemsSource="{Binding OdbcDataSources, Mode=TwoWay}"
Grid.Row="1" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Server}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Border
x:Name="Bd"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<StackPanel Orientation="Vertical">
<Label Content="{Binding Server}" />
<Label Content="{Binding Driver}" />
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>

WPF Custom ComboBox Showing "System.Windows.Styles" on item

I created a custom WPF ComboBox like this:
<ComboBox
x:Name="ComboBoxBtn"
VerticalAlignment="Top"
HorizontalAlignment="Left"
Margin="0,0,0,-1"
Width="300"
ItemsSource="{Binding Source, RelativeSource={RelativeSource AncestorType=UserControl}}"
SelectedItem="{Binding Path=Selected, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=UserControl}}"
IsSynchronizedWithCurrentItem="True">
<ComboBox.ItemTemplate>
<DataTemplate>
<ContentControl>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding Favorite}" Value="True">
<Setter Property="Content">
<Setter.Value>
<Grid>
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="Background" Value="#FFE6E6FA"/>
</Style>
</Grid.Style>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Content="{Binding}" Width="250" />
<Button Grid.Column="1" Command="{Binding AddCommandButton, ElementName=root}"
CommandParameter="{Binding}">+</Button>
</Grid>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Favorite}" Value="False">
<Setter Property="Content">
<Setter.Value>
<Grid>
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="Background" Value="Yellow"/>
</Style>
</Grid.Style>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Content="{Binding}" Width="250" />
<Button Grid.Column="1" Command="{Binding RemoveCommandButton, ElementName=root}"
CommandParameter="{Binding}">-</Button>
</Grid>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
The Source binding contains a ObservableColleciton where the client has a Favorite field and is supposed to show a different background and a different button. But when I open the ComboBox all the items have:
"System.Windows.Styles"
Your problem is you are setting Style as Content in the Content Control.
<ContentControl>
<Style TargetType="ContentControl">
...
</Style>
</ContentControl>
In order to set the style of the content control you should add:
<ContentControl.Style>
So the code above will look like this:
<ContentControl>
<ContentControl.Style>
<Style TargetType="ContentControl">
...
</Style>
<ContentControl.Style>
</ContentControl>
EDIT
By the way your code is very complex for the simple task of changing the background. Here is a simplified version:
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid Name="PART_GRID" Background="Yellow">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Content="{Binding}"
Width="250" />
<Button Name="PART_BUTTON"
Grid.Column="1"
Content="-"
Command="{Binding AddCommandButton, ElementName=root}"
CommandParameter="{Binding}" />
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Favorite}"
Value="True">
<Setter TargetName="PART_GRID"
Property="Background"
Value="#FFE6E6FA" />
<Setter TargetName="PART_BUTTON"
Property="Content"
Value="+" />
<Setter TargetName="PART_BUTTON"
Property="Command"
Value="{Binding RemoveCommandButton, ElementName=root}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ComboBox.ItemTemplate>
In my case, I found that I had:
<ComboBox>
<Style>
</Style>
</ComboBox>
which was directly adding a style as an item, which is similar to the solution above.

Base Expander Style, override header color

Is it possible to create some sort of base expander style and override the background color of the header in a derived style?
In my application I'm using expanders a lot and I would like to change the background color of the header. I know I could just copy&paste my style and edit the color, but it would be nicer to just create a new style based on the "base style" and setting the header's background color.
But I do not know how to access this color.
It's the color of this line: below I'd like to change (the border in the header): Border Name="border"... I cannot access "border" in the setter of the derived style...
This is my (base) style:
<Style TargetType="Expander" x:Key="ExpanderStyle">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextColor}}"/>
<Setter Property="Template">
<Setter.Value>
<!-- Control template for expander -->
<ControlTemplate TargetType="Expander" x:Name="exp">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Name="ContentRow" Height="0"/>
</Grid.RowDefinitions>
<Border Name="border" Grid.Row="0" Background="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" BorderThickness="1" CornerRadius="4,4,0,0" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<ToggleButton x:Name="tb" FontFamily="Marlett" FontSize="9.75" Background="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" Foreground="Black" Grid.Column="1" Content="u" IsChecked="{Binding Path=IsExpanded,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}" />
<ContentPresenter x:Name="HeaderContent" Grid.Column="0" Margin="4" ContentSource="Header" RecognizesAccessKey="True" />
</Grid>
</Border>
<Border x:Name="Content" Grid.Row="1" BorderThickness="1,0,1,1" CornerRadius="0,0,4,4" >
<ContentPresenter Margin="4" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="ContentRow" Property="Height" Value="{Binding ElementName=Content,Path=Height}" />
<Setter Property="Content" TargetName="tb" Value="t"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I would like to do something like this:
<Style x:Key="ExpanderStyleRed" BasedOn="{StaticResource ExpanderStyle}" TargetType="Expander">
<Setter Property="???" Value="Red"/>
<Style>
Use TemplateBinding:
<Style TargetType="Expander" x:Key="ExpanderStyle">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextColor}}"/>
<Setter Property="Template">
<Setter.Value>
<!-- Control template for expander -->
<ControlTemplate TargetType="Expander" x:Name="exp">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Name="ContentRow" Height="0"/>
</Grid.RowDefinitions>
<Border Name="border" Grid.Row="0" Background="{TemplateBinding Background}" BorderThickness="1" CornerRadius="4,4,0,0" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<ToggleButton x:Name="tb" FontFamily="Marlett" FontSize="9.75" Background="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" Foreground="Black" Grid.Column="1" Content="u" IsChecked="{Binding Path=IsExpanded,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}" />
<ContentPresenter x:Name="HeaderContent" Grid.Column="0" Margin="4" ContentSource="Header" RecognizesAccessKey="True" />
</Grid>
</Border>
<Border x:Name="Content" Grid.Row="1" BorderThickness="1,0,1,1" CornerRadius="0,0,4,4" >
<ContentPresenter Margin="4" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="ContentRow" Property="Height" Value="{Binding ElementName=Content,Path=Height}" />
<Setter Property="Content" TargetName="tb" Value="t"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderStyleRed" BasedOn="{StaticResource ExpanderStyle}" TargetType="Expander">
<Setter Property="Background" Value="#2fff0000"/>
</Style>
And then:
<Grid>
<Expander x:Name="expander1" Style="{DynamicResource ExpanderStyle}" Header="Expander" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="7,10,0,0" Height="108">
<TextBlock Width="250" Height="150" TextWrapping="Wrap">
asklsaklsa saaskklsaklas alsaklalkjd
asklsaklsaklsa saklsaklsakl jsajkjska
saklsaklsakl sasa
</TextBlock>
</Expander>
<Expander x:Name="expander2" Style="{DynamicResource ExpanderStyleRed}" Header="Expander" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="12,126,0,0" Height="133">
<TextBlock Width="250" Height="150" TextWrapping="Wrap">
asklsaklsa saaskklsaklas alsaklalkjd
asklsaklsaklsa saklsaklsakl jsajkjska
saklsaklsakl sasa
</TextBlock>
</Expander>
</Grid>

Listbox/listview vertical scrollbar does not show (horizontal yes)

I've a listbox defined in xaml like this:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="21" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="23" />
<ColumnDefinition Width="23" />
<ColumnDefinition Width="23" />
<ColumnDefinition Width="4" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="26" />
<RowDefinition Height="*" />
<RowDefinition Height="4" />
</Grid.RowDefinitions>
<ListBox x:Name="AInLb" Margin="8,6,8,8" BorderBrush="Gray" Grid.Row="1" Grid.ColumnSpan="6" Grid.RowSpan="2" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsSelected" Value="{Binding Content.IsSelected, Mode=TwoWay, RelativeSource={RelativeSource Self}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListView x:Name="AInfoLv" FontFamily="Khmer UI" Background="White" BorderBrush="{x:Null}" BorderThickness="0" Foreground="Black">
<ListView.View>
<GridView>
<GridViewColumn x:Name="LabelColumn" Header="Label" Width="110" DisplayMemberBinding="{Binding Path=Label}" />
<GridViewColumn x:Name="ValueColumn" Header="Value" Width="140" DisplayMemberBinding="{Binding Path=Value}" />
</GridView>
</ListView.View>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border BorderBrush="Transparent" BorderThickness="1" Background="{TemplateBinding Background}">
<GridViewRowPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Label}" Value="Login">
<Setter Property="FontWeight" Value="Bold"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Label}" Value="Skill(s)">
<Setter Property="FontWeight" Value="Bold"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</ListBox>
The height and width for both listbox and listview are set to auto. When the content exceeded the height and width of the listbox, the horizontal scrollbar works fine, but the vertical scrollbar does not show.
Update:
Included #Dom's suggestion.
Update 2:
After Height limit is set for the listbox.
The problem solved by setting ScrollViewer.CanContentScroll="False" for the ListBox. Reference.
The ListView alreas a ScrollViewer. You need to enable it:
<ListView ScrollViewer.CanContentScroll="True"
Scro

Categories