I have a list view which contain a stack panel. which contain a data grid.
I want that the user will click on a check box.
and some of the data will collapsed. (and rest of the data will go up) for any list view Item
will be appericate some help with code exmpale:
attching some of my XAML code:
<Style x:Key="ShowHideStyle" TargetType="StackPanel" >
<Style.Setters>
<Setter Property="Visibility" Value="Collapsed" />
</Style.Setters>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Value="True">
<Condition.Binding>
<MultiBinding Converter="{StaticResource V_converter }">
<Binding Path="Type"></Binding>
<Binding Path="NodeID"></Binding>
<Binding Path="TLV"></Binding>
</MultiBinding>
</Condition.Binding>
</Condition>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Visibility" Value="Visible" />
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
<ListView x:Name="LV" ItemsSource= "{Binding Lggv}" SelectionChanged="dataGridData_SelectionChanged" ItemContainerStyle="{StaticResource ListViewItemStyle}">
<ListView.ItemTemplate>
<DataTemplate x:Name="DT" >
<StackPanel x:Name="LVSP" DataContextChanged="LVSP_DataContextChanged" SourceUpdated="LVSP_SourceUpdated" Style="{StaticResource ShowHideStyle}">
<Border BorderThickness="1" BorderBrush="Black" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"></ColumnDefinition>
<ColumnDefinition Width="55"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock x:Name="tbHeader" Text="{Binding Info }" AllowDrop="True" FontWeight="Bold" Grid.Column="2" Visibility="{Binding Visibility_Header}" >
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Background">
<Setter.Value>
<!-- this is the default background-->
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFCEE6C6" Offset="0.008"/>
<GradientStop Color="#FF9ECF8C" Offset="0.987"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
</Border>
<Grid x:Name="GridData">
<Grid.Background>
<MultiBinding Converter="{StaticResource converter }">
<Binding Path="Type"></Binding>
<Binding Path="NodeID"></Binding>
<Binding Path="TLV"></Binding>
</MultiBinding>
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"></ColumnDefinition>
<ColumnDefinition Width="55"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" BorderThickness="1" BorderBrush="Black">
<TextBlock Text="{Binding DateTime}" ></TextBlock>
</Border>
<Border Grid.Column="1" BorderThickness="1" BorderBrush="Black">
<TextBlock Text="{Binding ComPort}"></TextBlock>
</Border>
<Border Grid.Column="2" BorderThickness="1" BorderBrush="Black">
<TextBlock Text="{Binding Data}" ></TextBlock>
</Border>
</Grid>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You should set the ItemContainerStyle for the targettype ListViewItem instead of targeting your item content (StackPanel).
In Resources section, define your style
<Style x:Key="ShowHideStyle" TargetType="ListViewItem">
...
</Style>
Then use it
<ListView ItemContainerStyle="{StaticResource ShowHideStyle}" .../>
Ofcourse, I assume that your converter/trigger thing is actually working and you just have the problem of properly hiding the whole list entry.
Put the StackPanel in an Expander and apply the style to the latter.
<ListView x:Name="LV" ItemsSource= "{Binding Lggv}" SelectionChanged="dataGridData_SelectionChanged"
ItemContainerStyle="{StaticResource ListViewItemStyle}">
<ListView.ItemTemplate>
<DataTemplate x:Name="DT" >
<Expander Header="..." Style="{StaticResource ShowHideStyle}">
<StackPanel x:Name="LVSP" DataContextChanged="LVSP_DataContextChanged" SourceUpdated="LVSP_SourceUpdated">
<Border...></Border...>
<Grid...></Grid...>
</StackPanel>
</Expander>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Instead of setting the Visbility property to Collapsed/Visible you set the IsExpanded property of the Expander to false/true:
<Style x:Key="ShowHideStyle" TargetType="Expander" >
<Style.Setters>
<Setter Property="IsExpanded" Value="False" />
</Style.Setters>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Value="True">
<Condition.Binding>
<MultiBinding Converter="{StaticResource V_converter }">
<Binding Path="Type"></Binding>
<Binding Path="NodeID"></Binding>
<Binding Path="TLV"></Binding>
</MultiBinding>
</Condition.Binding>
</Condition>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="IsExpanded" Value="True" />
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
Related
I have a code like this:
<ListBox Name="lstBox"
ItemsSource="{Binding ViewModelsView}"
SelectedItem="{Binding SelectedAlertViewOutput, Mode=OneWayToSource}">
<ListBox.Style>
<Style TargetType="{x:Type ListBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}" Padding="1" >
<ScrollViewer Padding="{TemplateBinding Padding}" >
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected"
Value="{Binding AlertRecord.IsSelected, Mode=TwoWay}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<controls:AlertExpander
Margin="1"
Value="{Binding AlertRecord.AlertCategory}"
IsExpanded="{Binding Path=IsSelected, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
IsActive="{Binding AlertRecord.IsActive, Mode=OneWay }"
StartTime="{Binding AlertRecord.Timestamp, Mode=OneWay}"
StopTime="{Binding AlertRecord.EndTimestamp, Mode=OneWay}"
AlertId="{Binding AlertRecord.Id, Mode=OneWay}"
<controls:AlertExpander.Content>
<ContentPresenter>
</ContentPresenter>
</controls:AlertExpander.Content>
</controls:AlertExpander>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Style>
<ListBox.Resources>
<DataTemplate DataType="{x:Type local:AlertUnknownViewModel}">
<local:AlertUnknownView></local:AlertUnknownView>
</DataTemplate>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="4">
<ContentPresenter Content="{Binding}"></ContentPresenter>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
ListBox uses my control AlertExpander as ListBoxItem.
Is it possible to create a list consisting not only of elements of type AlertExpander? I would like for an element of another type to also use the parameters on which AlertExpander depends.
I have several types of controls that accept the same parameters as AlertExpander, but look different, and I need to display elements of all types in the list, not just AlertExpander.
AlertExpander.xaml:
<Expander
<Control.Style>
<Style TargetType="Expander">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Expander">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Header -->
<ToggleButton Name="HeaderButton">
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="IsChecked" Value="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, UpdateSourceTrigger=PropertyChanged}"/>
<Setter Property="IsEnabled" Value="{Binding Path=Expandable, RelativeSource={RelativeSource AncestorType=controls:AlertExpander}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid>
<Border Grid.Row="1" BorderThickness="1" BorderBrush="Black"
CornerRadius="{Binding BorderCornerRadius, RelativeSource={RelativeSource AncestorType=controls:AlertExpander}, Mode=OneWay}">
</Border>
<!-- Border shade -->
<Border Name="BorderShade" Grid.Row="1" BorderThickness="1" BorderBrush="Transparent" Visibility="Collapsed"
</Border>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2" Margin="10">
<Image.OpacityMask>
<ImageBrush ImageSource="{Binding SelectedItem.IconSource, RelativeSource={RelativeSource AncestorType=controls:AlertExpander}, Mode=OneWay}"/>
</Image.OpacityMask>
<Image.Source>
<MultiBinding Mode="OneWay" Converter="{converters:GrayscaleImageSourceConverter}">
<Binding Path="SelectedItem" RelativeSource="{RelativeSource AncestorType=controls:AlertExpander}"/>
<Binding Path="IsActive" RelativeSource="{RelativeSource AncestorType=controls:AlertExpander}"/>
</MultiBinding>
</Image.Source>
</Image>
<StackPanel x:Name="topHeader" Grid.Row="0" Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Bottom">
</StackPanel>
<Label x:Name="bottomHeader" Grid.Row="1" Grid.Column="1" VerticalAlignment="Top" Background="Transparent" Padding="0,2,0,0" FontSize="9pt"
Content="{Binding AlertHeaderTime, RelativeSource={RelativeSource AncestorType=controls:AlertExpander}, Mode=OneWay}">
</Label>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="BorderShade" Property="Visibility" Value="Visible"/>
</Trigger>
<DataTrigger Binding="{Binding IsAlertHeaderTimeShown, RelativeSource={RelativeSource AncestorType=controls:AlertExpander}, Mode=OneWay}" Value="false">
<Setter TargetName="topHeader" Property="VerticalAlignment" Value="Center"/>
<Setter TargetName="topHeader" Property="Grid.RowSpan" Value="2"/>
<Setter TargetName="bottomHeader" Property="Visibility" Value="Hidden"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid>
<Border Grid.Row="1" BorderThickness="1" BorderBrush="Black"
CornerRadius="{Binding BorderCornerRadius, RelativeSource={RelativeSource AncestorType=controls:AlertExpander}, Mode=OneWay, Converter={converters:AlertExpanderCornerRadiusTopConverter}}">
</Border>
<!-- Border shade -->
<Border Name="BorderShade" Grid.Row="1" BorderThickness="1" BorderBrush="Transparent" Visibility="Collapsed"
Background="{Binding MouseOverShade, RelativeSource={RelativeSource AncestorType=controls:AlertExpander}, Mode=OneWay}"
CornerRadius="{Binding BorderCornerRadius, RelativeSource={RelativeSource AncestorType=controls:AlertExpander}, Mode=OneWay, Converter={converters:AlertExpanderCornerRadiusTopConverter}}">
</Border>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2" Margin="10">
<Image.OpacityMask>
<ImageBrush ImageSource="{Binding SelectedItem.IconSource, RelativeSource={RelativeSource AncestorType=controls:AlertExpander}, Mode=OneWay}"/>
</Image.OpacityMask>
<Image.Source>
<MultiBinding Mode="OneWay" Converter="{converters:GrayscaleImageSourceConverter}">
<Binding Path="SelectedItem" RelativeSource="{RelativeSource AncestorType=controls:AlertExpander}"/>
<Binding Path="IsActive" RelativeSource="{RelativeSource AncestorType=controls:AlertExpander}"/>
</MultiBinding>
</Image.Source>
</Image>
<StackPanel x:Name="topHeader" Grid.Row="0" Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Bottom">
<Label Background="Transparent" Padding="0,0,0,2" FontSize="12pt"
FontWeight="{Binding IsActive, Mode=OneWay, RelativeSource={RelativeSource AncestorType=controls:AlertExpander}, Converter={converters:BoolToFontWeightConverter}}"
Content="{Binding AlertHeader, RelativeSource={RelativeSource AncestorType=controls:AlertExpander}, Mode=OneWay}">
</Label>
<Label Background="Transparent" Padding="4,0,0,2" FontSize="12pt"
FontWeight="{Binding IsActive, Mode=OneWay, RelativeSource={RelativeSource AncestorType=controls:AlertExpander}, Converter={converters:BoolToFontWeightConverter}}"
Visibility="{Binding IsActive, Mode=OneWay, RelativeSource={RelativeSource AncestorType=controls:AlertExpander}, Converter={converters:InactiveNoteVisibilityConverter}}"
Content="{Binding InactiveNote, RelativeSource={RelativeSource AncestorType=controls:AlertExpander}, Mode=OneWay}">
</Label>
</StackPanel>
<Label x:Name="bottomHeader" Grid.Row="1" Grid.Column="1" VerticalAlignment="Top" Background="Transparent" Padding="0,2,0,0" FontSize="9pt"
Content="{Binding AlertHeaderTime, RelativeSource={RelativeSource AncestorType=controls:AlertExpander}, Mode=OneWay}">
</Label>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="BorderShade" Property="Visibility" Value="Visible"/>
</Trigger>
<DataTrigger Binding="{Binding IsAlertHeaderTimeShown, RelativeSource={RelativeSource AncestorType=controls:AlertExpander}, Mode=OneWay}" Value="false">
<Setter TargetName="topHeader" Property="VerticalAlignment" Value="Center"/>
<Setter TargetName="topHeader" Property="Grid.RowSpan" Value="2"/>
<Setter TargetName="bottomHeader" Property="Visibility" Value="Hidden"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
<!-- Content -->
<ScrollViewer Name="ContentScrollViewer" Grid.Row="1"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Bottom"
Visibility="Visible">
<Border Name="ExpanderContentBorder" BorderThickness="1,0,1,1" BorderBrush="Black">
<ContentPresenter ContentSource="Content"/>
</Border>
</ScrollViewer>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Control.Style>
enter image description here
Before I get to the code, I want to point out that this is a job for data templates, rather than control templates.
The Template property takes a ControlTemplate and is used to define the structure of a control. This is usually used when you are building a control from scratch or significantly altering one. What you want to do is just change how your data is being displayed inside an existing control. For that, there are DataTemplate properties, such as ItemTemplate.
With that out of the way, I put together some code for you that should at least point you in the right direction:
<ListBox Name="lstBox" ItemsSource="{Binding ViewModelsView}" SelectedItem="{Binding SelectedAlertViewOutput, Mode=OneWayToSource}">
<ListBox.Resources>
<DataTemplate DataType="local:AlertRecord" x:Key="AlertExpanderItem">
<controls:AlertExpander Margin="1"
Value="{Binding AlertCategory}"
IsExpanded="{Binding IsSelected, Mode=TwoWay}"
IsActive="{Binding IsActive, Mode=OneWay }"
StartTime="{Binding Timestamp, Mode=OneWay}"
StopTime="{Binding EndTimestamp, Mode=OneWay}"
AlertId="{Binding Id, Mode=OneWay}"/>
</DataTemplate>
<DataTemplate DataType="local:AlertRecord" x:Key="OtherControlItem">
<controls:OtherControl Margin="1"
Value="{Binding AlertCategory}"
IsExpanded="{Binding IsSelected, Mode=TwoWay}"
IsActive="{Binding IsActive, Mode=OneWay }"
StartTime="{Binding Timestamp, Mode=OneWay}"
StopTime="{Binding EndTimestamp, Mode=OneWay}"
AlertId="{Binding Id, Mode=OneWay}"/>
</DataTemplate>
</ListBox.Resources>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="ContentTemplate" Value="{StaticResource OtherControlItem}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Value}" Value="0">
<Setter Property="ContentTemplate" Value="{StaticResource AlertExpanderItem}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
...
public class AlertRecord
{
...
public bool HasPositiveValue { get { return Value >= 0 } }
...
}
I start by defining two different ItemTemplates inside inside the Resources of the ListBox. You would define one for each of the different controls you need to use. Notice that I left off "AlertRecord." from the bindings. That is because each DataTemplate instance will have the AlertRecord as its DataContext.
For the ItemTemplate property, I borrowed from this answer here: https://stackoverflow.com/a/10191762/5086631. I made a DataTemplate with a ContentControl and used the Style to change the ContentTemplate based on DataTriggers. This lets you change the template based on the properties of your list item.
Based on your comment, the style is set up so that "OtherControlItem" (the non-expander control) is used by default, and AlertExpanderItem is used when HasPositiveValue returns true. HasPositiveValue is a property you would need to add to AlertRecord.
I have a textbox:
<TextBox Grid.Row="3"
Grid.Column="1"
Width="200"
TextWrapping="Wrap"
VerticalAlignment="Top"
Margin="5,10,-10,2"
Style="{StaticResource TextBoxValueStyle}"
Validation.ErrorTemplate="{StaticResource ValidationControlTemplate}">
<TextBox.Text>
<MultiBinding StringFormat=" {0} {1}">
<Binding Path="Id" ValidatesOnNotifyDataErrors="True" NotifyOnValidationError="True"/>
<Binding Path="Name" />
</MultiBinding>
</TextBox.Text>
</TextBox>
And here is my controltemplate:
<ControlTemplate x:Key="ValidationControlTemplate">
<DockPanel Visibility="{Binding ElementName=Placeholder, Path=Visibility}">
<Image x:Name="Image"
DockPanel.Dock="Right"
VerticalAlignment="Center"
Margin="0,-2"
Style="{StaticResource InformationImageStyle}">
<Image.ToolTip>
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ErrorContent}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Image.ToolTip>
</Image>
<AdornedElementPlaceholder Name="Placeholder" VerticalAlignment="Center"/>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="TextBox.Text" Value="">
<Setter Property="DockPanel.Dock" TargetName="Image" Value="Left"/>
<Setter Property="Margin" TargetName="Image" Value="-20,-2"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
My issue is that when the textbox has a value (and has error)it is NOT taking the original values (DockPanel.Dock=Right and Margin=0,-2)
I am always starting with text empty. The image is always showing to the left, on error.
What am I missing?
Put a Grid around the <AdornedElementPlaceholder /> element and replace the Trigger with a DataTrigger that binds to the adorned TextBox element:
<ControlTemplate x:Key="ValidationControlTemplate">
<DockPanel Visibility="{Binding ElementName=Placeholder, Path=Visibility}">
<Image x:Name="Image"
DockPanel.Dock="Right"
VerticalAlignment="Center"
Margin="0,-2"
Style="{StaticResource InformationImageStyle}">
<Image.ToolTip>
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ErrorContent}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Image.ToolTip>
</Image>
<Grid>
<AdornedElementPlaceholder Name="Placeholder" VerticalAlignment="Center"/>
</Grid>
</DockPanel>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding AdornedElement.Text.Length, ElementName=Placeholder}" Value="0">
<Setter Property="DockPanel.Dock" TargetName="Image" Value="Left"/>
<Setter Property="Margin" TargetName="Image" Value="-20,-2"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
I'm searching how to change the background color of my WPF Listbox, nothing worked... I don't want to change the background of the Item Template, but of the ListBox himself.
I tried the differents solutions answered here Answers
Here is my Listbox :
<ListBox Name="myListBox" ScrollViewer.VerticalScrollBarVisibility="Visible" SelectionChanged="myListBox_SelectionChanged" Background="#FFC3DDF7" Margin="0,0,0,10">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Value.IsOk}" Value="True">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel Width="200">
<TextBlock FontSize="10" FontWeight="Bold" VerticalAlignment="Center" Text="{Binding Path=Key}" />
<TextBlock FontSize="10" VerticalAlignment="Center" TextWrapping="Wrap">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1} {2}">
<Binding Path="Value.TextA" />
<Binding Path="Value.TextB" />
<Binding Path="Value.TextC" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Maybe the item template is on the foreground ?
Tried these codes :
<ListBox.Style>
<Style TargetType="{x:Type ListBox}">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Blue"/>
</Style.Resources>
</Style>
and
<ListBox>
<ListBox.Style>
<Style TargetType="{x:Type ListBox}">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Style>
</ListBox>
Not working. The down right corner, between the two scrollbars, became blue... But that's all !
The reason why your linked answer does not work is because you have the background of the listbox set to #FFC3DDF7 on the element itself. If you wish to change the initial background color of your listbox this would need to be moved into the style. If you do not move this then the rule for "closest" defined value would be the one on the element itself and the style can't override this.
<ListBox Name="myListBox" ScrollViewer.VerticalScrollBarVisibility="Visible" SelectionChanged="myListBox_SelectionChanged" Margin="0,0,0,10">
<ListBox.Style>
<Style TargetType="{x:Type ListBox}">
<Setter Property="Background" Value="#FFC3DDF7"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="LightGray" />
<Setter Property="Background" Value="LightGray" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Style>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Value.IsOk}" Value="True">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel Width="200">
<TextBlock FontSize="10" FontWeight="Bold" VerticalAlignment="Center" Text="{Binding Path=Key}" />
<TextBlock FontSize="10" VerticalAlignment="Center" TextWrapping="Wrap">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1} {2}">
<Binding Path="Value.TextA" />
<Binding Path="Value.TextB" />
<Binding Path="Value.TextC" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
As Anthony pointed out, your style trigger will never set the Background of your ListBox because you have set a local value. It's called "Dependency Property Precedence". Take a look at this link: https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/dependency-property-value-precedence.
"Local" values have higher precedence over "style trigger" values. However, "style trigger" values have higher precedence over "style setter" values. This means that if you want to have an initial value for the property and change it based on a trigger, just set it in the style initially, instead of setting it locally like your code does.
First off all - this msdn link ListBox Styles and Templates will help you the most. You can check this way - what applies where in a ListBox and a ListBoxItem.
If you check the Style of the ListBoxItem you will see that the ContentPresenter gets no Foreground applied.
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter x:Name="contentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"/><!-- No foreground gets applied. -->
<Rectangle x:Name="FocusVisualElement" Stroke="#FF6DBDD1" StrokeThickness="1" Visibility="Collapsed" RadiusX="1" RadiusY="1" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Anyway here is your solution:
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
Width="200">
<TextBlock VerticalAlignment="Center"
FontSize="10"
TextWrapping="Wrap">
<Run FontWeight="Bold" Text="{Binding Path=Key}" />
<LineBreak />
<Run>
<Run.Text>
<MultiBinding StringFormat="{}{0} {1} {2}">
<Binding Path="Value.TextA" />
<Binding Path="Value.TextB" />
<Binding Path="Value.TextC" />
</MultiBinding>
</Run.Text>
</Run>
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsOk}" Value="True" >
<Setter Property="Foreground" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
The TextBlock now listens to isOk and will applys the Foreground.
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.
I am making diagram (with help of the google of course). Simple nice working diagram, but I have little issues.
When I have referenced to Canvas.Top everything works nice, just Y axis is upside down .. so Y is getting from 0 to positive when moving mouse down and I like it that positive/higher value is at top and 0 is at bottom. When I reference Canvas to Bottom my points/nodes works fine only connectors/lines are still reference to "top".
How to add also the connectors/lines to Canvas.Bottom referencing.
Here is my XAML code:
<Grid>
<Grid.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
<CompositeCollection x:Key="DiagramCol">
<CollectionContainer Collection="{Binding DataContext.DiagramConnectors, Source={x:Reference diagramview}}"/>
<CollectionContainer Collection="{Binding DataContext.DiagramNodes, Source={x:Reference diagramview}}"/>
</CompositeCollection>
<!--NODES-->
<DataTemplate DataType="{x:Type local:DiagramNode}">
<Canvas Name="dragTarget">
<Thumb DragDelta="Thumb_Drag" DragStarted="Thumb_DragStarted" DragCompleted="Thumb_DragCompleted">
<Thumb.Template>
<ControlTemplate TargetType="Thumb">
<Canvas Margin="-10,-10,10,10">
<Ellipse Height="17" Width="17" Stroke="Black" StrokeThickness="1" Fill="Yellow"
x:Name="Ellipse"/>
<TextBlock Canvas.Top="-20" Canvas.Left="-40" Width="100"
TextAlignment="Center" Text="{Binding Name}" FontWeight="Bold"
IsHitTestVisible="False"
Visibility="{Binding DataContext.ShowNames,
RelativeSource={RelativeSource FindAncestor, AncestorType=Window},
Converter={StaticResource BoolToVisibilityConverter}}"/>
<TextBlock Canvas.Left="30" Canvas.Top="10"
Text="{Binding X, StringFormat='{}X = {0}'}"
IsHitTestVisible="False"
Visibility="Visible" x:Name="XText"/>
<TextBlock Canvas.Left="30" Canvas.Top="25"
Text="{Binding Xmeaning}"
IsHitTestVisible="False"
Visibility="Visible" x:Name="timeText"/>
<TextBlock Canvas.Left="30" Canvas.Top="40"
Text="{Binding Y, StringFormat='{}Y = {0}'}"
IsHitTestVisible="False"
Visibility="Visible" x:Name="YText"/>
<TextBlock Canvas.Left="30" Canvas.Top="55"
Text="{Binding Ymeaning}"
IsHitTestVisible="False"
Visibility="Visible" x:Name="luxText"/>
</Canvas>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" Value="True">
<Setter TargetName="Ellipse" Property="Fill" Value="Red"/>
</DataTrigger>
<Trigger Property="IsDragging" Value="True">
<Setter TargetName="Ellipse" Property="Fill" Value="Green"/>
</Trigger>
<DataTrigger Binding="{Binding DataContext.ShowAllCoordinates, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" Value="True">
<Setter TargetName="XText" Property="Visibility" Value="Visible"/>
<Setter TargetName="YText" Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding }" Value="True">
<Setter TargetName="Ellipse" Property="StrokeThickness" Value="2"/>
<Setter TargetName="Ellipse" Property="Stroke" Value="Red"/>
<Setter TargetName="Ellipse" Property="Fill" Value="White"/>
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" Value="True"/>
<Condition Binding="{Binding DataContext.ShowCurrentCoordinates, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter TargetName="XText" Property="Visibility" Value="Visible"/>
<Setter TargetName="YText" Property="Visibility" Value="Visible"/>
</MultiDataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Canvas>
</DataTemplate>
<!--CONNECTORS-->
<DataTemplate DataType="{x:Type local:DiagramConnector}">
<Line Stroke="OrangeRed" StrokeThickness="3"
X1="{Binding Start.X}" Y1="{Binding Start.Y}"
X2="{Binding End.X}" Y2="{Binding End.Y}" x:Name="Line"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Start}" Value="{x:Null}">
<Setter TargetName="Line" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Grid.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Name="column1" Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="23" />
<RowDefinition Name="row1" Height="*"/>
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<TextBlock Margin="2" x:Name="tbTitle" Grid.Column="1" Grid.Row="0" RenderTransformOrigin="0.5,0.5" FontSize="14" FontWeight="Bold" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" TextAlignment="Center" Text="{Binding GraphAddress}"/>
<TextBlock Margin="2" x:Name="tbXlabel" Grid.Column="1" Grid.Row="3" RenderTransformOrigin="0.5,0.5" TextAlignment="Center" Text="{Binding Xlabellabel}" />
<TextBlock Margin="2" x:Name="tbYlabelLeft" Grid.Column="0" Grid.Row="1" RenderTransformOrigin="0.5,0.5" TextAlignment="Center" Text="{Binding Ylabelleftlabel}">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
<TextBlock Margin="2" x:Name="tbYlabelRight" Grid.Column="2" Grid.Row="1" RenderTransformOrigin="0.5,0.5" TextAlignment="Center" Text="{Binding Ylabelrightlabel}">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
<ListBox SelectedItem="{Binding SelectedObject}"
PreviewMouseMove="ListBox_PreviewMouseMove"
PreviewMouseDown="ListBox_PreviewMouseDown"
PreviewMouseRightButtonDown="ListBox_PreviewMouseRightButtonDown"
PreviewMouseLeftButtonDown="ListBox_PreviewLeftMouseDown"
Margin="10,10,10,10"
Grid.Column="1"
Grid.Row="1"
x:Name="LstBox">
<ListBox.Template>
<ControlTemplate>
<Border>
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" Opacity=".3">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="LightGray" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<Border>
<Border.Background>
<VisualBrush TileMode="Tile"
Viewport="0,0,36,36" ViewportUnits="Absolute"
Viewbox="0,0,20,20" ViewboxUnits="Absolute">
<VisualBrush.Visual>
<Rectangle Stroke="Darkgray" StrokeThickness="0.5" Height="24" Width="24"
StrokeDashArray="5 3"/>
</VisualBrush.Visual>
</VisualBrush>
</Border.Background>
<ItemsPresenter/>
</Border>
</ScrollViewer>
</Border>
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemsSource>
<StaticResource ResourceKey="DiagramCol"/>
</ListBox.ItemsSource>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True" Background="#01FFFFFF"
Height="{Binding AreaHeight}" Width="{Binding AreaWidth}"
VerticalAlignment="Top" HorizontalAlignment="Left"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Canvas.Left" Value="{Binding X}"/>
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource EmptyFocusVisualStyle}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter x:Name="Content"/>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Content" Property="Effect">
<Setter.Value>
<DropShadowEffect Color="Gray" ShadowDepth="4" BlurRadius="10"/>
</Setter.Value>
</Setter>
</Trigger>
<DataTrigger Binding="{Binding IsNew}" Value="True">
<Setter Property="Opacity" Value=".5"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</Grid>
</Grid>
So when I reference this line:
<Setter Property="Canvas.Top" Value="{Binding Y}"/>
To:
<Setter Property="Canvas.Bottom" Value="{Binding Y}"/>
then points/nodes works fine. Only the lines are the issue. In the code I like to add datatemplate of line to canvas bottom referencing, but how?
Please help. If any question please ask and if anything missing what you need, please say :)