Trying to use the same control for displaying a column with images and without, depending on a boolean (HistoryOn). Next xaml code works, but always shows the images.
<DataGridTemplateColumnx:Name="dgtc">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding
Converter={StaticResource myDataRowToListConverter}}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border x:Name="imageBorder" BorderThickness="1" BorderBrush="Black"
MouseLeave="imageBorder_MouseLeave"
MouseEnter="imageBorder_MouseEnter"Height="16">
<Image x:Name="myImage" Source="{BindingMyImagePath}"
MouseUp="Image_MouseUp" HorizontalAlignment="Center">
</Image>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Next xaml code displays only the path, not the images. What is wrong?
<DataGridTemplateColumn x:Name="dgtc">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding
Converter={StaticResource myDataRowToListConverter}}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding MyImagePath}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding HistoryOn}" Value="true">
<Setter Property="ContentTemplate"
Value="{StaticResource imagesOff}" />
</DataTrigger>
<DataTrigger Binding="{Binding HistoryOn}" Value="false">
<Setter Property="ContentTemplate"
Value="{StaticResource imagesOn}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
In the Windows.Resources:
<DataTemplate x:Key="imagesOn">
<Border x:Name="imageBorder1" BorderThickness="1" BorderBrush="Black"
MouseLeave="imageBorder_MouseLeave"
MouseEnter="imageBorder_MouseEnter"Height="16">
<Image x:Name="myImage" Source="{BindingMyImagePath}"
MouseUp="Image_MouseUp"HorizontalAlignment="Center">
</Image>
</Border>
</DataTemplate>
<DataTemplatex:Key="imagesOff">
<Border x:Name="imageBorder2" BorderThickness="1" BorderBrush="Black"
MouseLeave="imageBorder_MouseLeave"
MouseEnter="imageBorder_MouseEnter"Height="16">
</Border>
</DataTemplate>
You can use CellTemplateSelector to Choose the desired template depending on the object take a look at this link to see a detailed example on this topic
Good Luck
Related
I want to display tooltip of different view depending on content of DataGridCell. The following code works.
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="1" Binding="{Binding}">
<DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip>
<ToolTip.Content>
<TextBlock Foreground="Blue" Text="{Binding}"></TextBlock>
</ToolTip.Content>
</ToolTip>
</Setter.Value>
</Setter>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
</DataGrid.Columns>
<DataGrid.Items>
<system:String>AAA</system:String>
<system:Int32>2</system:Int32>
</DataGrid.Items>
</DataGrid>
But when I try using templates I have no success (I want select template basing on type of view model).
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="1" Binding="{Binding}">
<DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip>
<ToolTip.ContentTemplate>
<DataTemplate>
<ContentControl Content="{Binding}">
<ContentControl.Resources>
<DataTemplate DataType="system:String">
<TextBlock Foreground="Blue" Text="{Binding}"></TextBlock>
</DataTemplate>
<DataTemplate DataType="system:Int32">
<TextBlock Foreground="Red" Text="{Binding}"></TextBlock>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</DataTemplate>
</ToolTip.ContentTemplate>
</ToolTip>
</Setter.Value>
</Setter>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
</DataGrid.Columns>
<DataGrid.Items>
<system:String>AAA</system:String>
<system:Int32>2</system:Int32>
</DataGrid.Items>
</DataGrid>
How to fix it?
Bind the Content property of the Tooltip itself to the DataContext and use explicit type specifications using {x:Type}:
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="1" Binding="{Binding}">
<DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip Content="{Binding}">
<ToolTip.ContentTemplate>
<DataTemplate>
<ContentControl Content="{Binding}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type system:String}">
<TextBlock Foreground="Blue" Text="{Binding}"></TextBlock>
</DataTemplate>
<DataTemplate DataType="{x:Type system:Int32}">
<TextBlock Foreground="Red" Text="{Binding}"></TextBlock>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</DataTemplate>
</ToolTip.ContentTemplate>
</ToolTip>
</Setter.Value>
</Setter>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
</DataGrid.Columns>
<DataGrid.Items>
<system:String>AAA</system:String>
<system:Int32>2</system:Int32>
</DataGrid.Items>
</DataGrid>
As the title says, i want to bind the property IsExpanded of my Expander to the Items.Count property of the ItemsControl, which is the Content of the Expander. I need this binding for more expanders so a style or something like that would be nice. I already tried some stuff found here or on other sites, but nothing worked.
Here is my actual code:
<Style x:Key="ExpanderStyleKey" TargetType="Expander">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Content.Items.Count}" Value="0">
<Setter Property="IsExpanded" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
Thank you for help!
EDIT:
Here is the code of one of my Expander:
<Expander Name="exp1"
Header="Expander1"
Style="{StaticResource ExpanderStyleKey}">
<ItemsControl Name="itcMain"
ItemsSource="{Binding Path=ListInCodeBehind, Mode=OneWay}">
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=ExampleProperty}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Expander>
Example,
<Expander>
<Expander.Style>
<Style TargetType="Expander">
<Setter Property="IsExpanded" Value="{Binding Content.Items.Count, Mode=OneWay, RelativeSource={RelativeSource Self}}"/>
</Style>
</Expander.Style>
<Expander.Content>
<ItemsControl>
<ItemsControl.Items>
<TextBlock Text="Item1"/>
<TextBlock Text="Item2"/>
<TextBlock Text="Item3"/>
</ItemsControl.Items>
</ItemsControl>
</Expander.Content>
</Expander>
Our project has a DataGrid that displays an image along with text in one of the columns. When a row is selected, since it's highlighted, the image is not visible correctly. Hence we want to change the image only for the selected row.
I know how to change the property such as background of the dataGridCell using <Style.Triggers>; but cannot figure out how to change Image that is embedded inside the <DataGridTemplateColumn.CellTemplate>. Can you please help me with this?
<DataGrid Name="dgCPAGrid" Grid.Row="2" Grid.Column="0" ItemsSource="{Binding CPAListDisplay, Mode=OneWay}" Margin="0,5,0,5" AutoGenerateColumns="False"
IsReadOnly="True" SelectionMode="Single"
SelectedItem="{Binding SelectedCPA, Mode=TwoWay}"
IsSynchronizedWithCurrentItem="False" AlternatingRowBackground="White"
HorizontalGridLinesBrush="Gray" VerticalGridLinesBrush="Gray" >
<DataGrid.Resources>
<Style x:Key="DGCellMGA" TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
<Setter Property="ToolTipService.IsEnabled" Value="False" />
<Setter Property="Background" Value="#f8f8d2" />
<Setter Property="TextBlock.TextAlignment" Value="Right"/>
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn Header="{b:CaptionBinding gridHeaderCPAName}" Width="Auto" MinWidth="125">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding CPAName}" />
<Image Source="/Images/TimelineIconGreenTransparent.gif" Margin="5,0,0,0" Height="15" Width="15" Visibility="{Binding StaticInd, Converter={StaticResource BoolVisConv}, ConverterParameter=inverse, Mode=OneWay}"/>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="{b:CaptionBinding gridHeaderCPAMGA}" Binding="{Binding MgaY1P}" MinWidth="50" Width="*" CellStyle="{StaticResource DGCellMGA}" />
</DataGrid.Columns>
</DataGrid>
Inside your cell's Template, add another Trigger (this time, a DataTrigger) that listens to the IsSelected property of the containing DataGridRow. Inside the DataTrigger, use the TargetName property of the Setter to tell it to modify the Source property of the Image (you have to give it an x:Name first):
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding CPAName}" />
<Image x:Name="image" Source="/Images/TimelineIconGreenTransparent.gif" Margin="5,0,0,0" Height="15" Width="15" Visibility="{Binding StaticInd, Converter={StaticResource BoolVisConv}, ConverterParameter=inverse, Mode=OneWay}"/>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=DataGridRow}}"
Value="True">
<Setter TargetName="image"
Property="Source"
Value="/Images/Whateveryourotherimageisnamed.gif" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
Ok I have an XElement that looks like:
<authentication mode="Forms">
<forms loginUrl="login.aspx" name=".LOGIN" protection="All" timeout="4800" path="/" />
</authentication>
Then in my XAML I setup a ContentControl that looks like:
<ContentControl Content="{Binding Data}">
<ContentControl.ContentTemplate>
<DataTemplate>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=Attribute[mode].Value}" Value="Forms">
<Setter Property="ContentTemplate" Value="{StaticResource FormsTemplate}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
Where Data is my public property that contains the XElement. My template looks like:
<DataTemplate x:Key="FormsTemplate">
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Login URL"/>
<TextBox Text="{Binding Path=Element[forms].Attribute[loginUrl].Value}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Name"/>
<TextBox Text="{Binding Path=Attribute[name].Value}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Protection"/>
<TextBox Text="{Binding Path=Attribute[protection].Value}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Timeout"/>
<TextBox Text="{Binding Path=Attribute[timeout].Value}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Path"/>
<TextBox Text="{Binding Path=Attribute[path].Value}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="passport">
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Redirect URL"/>
<TextBox Text="{Binding Path=Attribute[redirectUrl].Value}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
Why doesn't this work? Nothing shows up on the screen when I do this.
I solved it by using a Style Trigger instead. Below is what I had to use for this to work.
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Data.Attribute[mode].Value}" Value="Forms">
<Setter Property="ContentTemplate" Value="{StaticResource FormsTemplate}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Data.Attribute[mode].Value}" Value="Passport">
<Setter Property="ContentTemplate" Value="{StaticResource PassportTemplate}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
I still didn't get it. Could you please show me exactly how to override ListBox's default behavior.
Everytime when ListBoxItem is selected the Border's background should be changed. Not the background of the whole row but only background of the border which's specified.
<ListBox ItemsSource="{Binding Source={StaticResource AssetsViewSource}}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderThickness="2" BorderBrush="Black">
<StackPanel>
<TextBlock Text="Name: " />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Use the DataTemplate's Triggers collection, with a RelativeSource to get you to the containing ListBoxItem:
<DataTemplate>
<Border BorderThickness="2" BorderBrush="Black" Name="Bd">
<StackPanel>
<TextBlock Text="Name: " />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</Border>
<DataTemplate.Triggers>
<DataTrigger Value="True"
Binding="{Binding
IsSelected,
RelativeSource={RelativeSource
AncestorType={x:Type ListBoxItem}}}">
<!-- everybody loves HotPink -->
<Setter TargetName="Bd" Property="Background" Value="HotPink"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
Simply add the following into the ListBox Item tag
<ListBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
</ListBox.Resources>
That should do the trick..