Storyboard for a DataTemplate element in Silverlight - silverlight

I have a DataGrid in my application, which have a column with defined CellTemplate with a text block and a button in it.
I want to show the button only when hover this specific cell. How can i achieve this?
Thanks in advance.

It may be possibly to script a templated storyboard that references other templated items, but I would be too terrified to try it that way :)
If you create the cell contents as a usercontrol (with a text box and button), the animation storyboards are then easily authored for that one control and run via attached ControlStoryboardAction behaviours (I can whip one up in minutes if you need an example).
The control properties for the text box etc need to expose both values and changes (e.g. by implementing them as INotifyPropertyChanged properties or even DependencyProperties), but then you can simply bind the CellTemplate to the child control instead of a TextBox.
Hope this helps.

Here's a solution which uses triggers.
<DataGrid>
<DataGrid.Items>
<System:String>hello</System:String>
<System:String>world</System:String>
</DataGrid.Items>
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid x:Name="MyGrid" Background="Transparent">
<StackPanel>
<TextBlock Text="{Binding}"/>
<Button x:Name="MyButton" Visibility="Hidden" Content="{Binding}"/>
</StackPanel>
</Grid>
<DataTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True" SourceName="MyGrid">
<Trigger.Setters>
<Setter TargetName="MyButton" Property="Visibility" Value="Visible"/>
</Trigger.Setters>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>

Related

Icon/Button That changes based on boolean binding value in MVVM

I've gotten this far with my XAML and wondering if I'm taking the right approach with regards to an icon/button to display data in a datagrid. I'm using Material Design.
I've got a boolean property in the viewmodel called "IsLocked". I want an icon in a column which will change to a lock or unlocked icon based on the value and I want to be able to click on the lock to change the value. I'm missing the button/click event. I'm trying to keep it in the XAML.
A bonus would be some UI feedback on mouseover to let the user know they can click it. How can I incorporate that too?
Is this the correct approach? How do I make it into something click-able?
<DataGridTemplateColumn Width="Auto" Header="Is Locked">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<materialDesign:PackIcon x:Name="LockIcon" Kind="LockOpenOutline" Foreground="Green"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding isLocked}" Value="True">
<Setter Property="Kind" Value="Lock" TargetName="LockIcon"/>
<Setter Property="Foreground" Value="Red" TargetName="LockIcon"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
You can create a converter which will return the PackIconKind and bind the isLocked property to the PackIcon with the converter.

Create combobox with different items design using data trigger

I have defined the names and color in the backend using C# so I want to select the item cat and change it's other elements.
You don't show the XAML you are using to set up the ComboBox but best approach is to use a data template to set up the ComboBox items however you wish them to look. If you want the color box to not be shown if the Color brush is null, you could then add a trigger to the template to make it Hidden. Note that if you make it collapsed it will realign the layout of the other controls.
<DataTemplate x:Key="cbDataTemplate">
<StackPanel Orientation="Horizontal">
<Rectangle x:Name="clrBox" Fill="{Binding Color, TargetNullValue=Transparent}"
Stroke="Black" StrokeThickness="2" Width="16"/>
<TextBlock Text="{Binding Name}" Margin="10,0,0,0"/>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Color}" Value="{x:Null}">
<Setter TargetName="clrBox" Property="Visibility" Value="Hidden"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
then to use this DataTemplate simply add it to the ComboBox like this:
<ComboBox ItemTemplate="{StaticResource cbDataTemplate}" Width="150"/>
hope that's helpful...

Click/focus on a ListBoxItem's content doesn't bubble up

I've got a ListBox that's declared like this:
<ListBox ItemsSource="{Binding Contracts}" SelectedItem="{Binding SelectedContract}">
<ListBox.ItemTemplate>
<DataTemplate>
<ListBoxItem Content="{Binding Name}">
<ListBoxItem.ToolTip>
<Grid>
[code omitted for reasons of clarity]
</Grid>
</ListBoxItem.ToolTip>
</ListBoxItem>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I expected the normal selection behavior since I play with the item's ToolTip rather than its content structure.
However, clicking an item's name doesn't focus/select that item. Only by clicking that tiny space between each item (easiest way would be the space between an item's name and the ListBox's border) the item gets focused/selected.
Of course, I googled around and thought I'd found the culprit (event doesn't bubble up). But any solution provided here on SO or elsewhere, e. g. adding code like this:
<ListBoxItem.Style>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
</ListBoxItem.Style>
turned out to not solve the problem. So, I assume I do something wrong and I'm just too blind to see it. And while there might be solutions using code-behind, I prefer to stick with clean and pure XAML.
Please help me, understanding my mistake and solving it.
if the purpose is add ToolTip for ListBoxItem, you can use ItemContainerStyle. ListBox creates ListBoxItems for each databound item, adding ListBoxItem into
DataTemplate isn't necessary, if it breaks some functionality, try to avoid it
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<Setter Property="ToolTip">
<Setter.Value>
<Grid>
<TextBlock Text="{Binding .}"/>
</Grid>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding .}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
edit: I used Snoop app to check your variant with ListBoxItem in DataTemplate. There is 2 ListBoxItems in visual tree of each ListBox element, maybe one of prevent selection of another

Conditionally changing the Foreground of a WPF ComboBox item depending upon a value in the databound ItemsSource item

I have a WPF ComboBox bound to a Collection List<Users>. I have applied a DataTemplate to show the FirstName using a TextBlock and this works as expected:
<ComboBox Margin="5" ItemsSource="{Binding Path=TheUsers}" Name="cboUsers">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Margin="10" Text="{Binding Path=FirstName}">
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>`
I have an item in my User class called IsActive which is a Boolean value. If true then I want to set the Foreground of the TextBlock to Navy.
I have spent so much time on what should be so easy and looked all over the web but most articles talk about changing the overall colour or binding to another element in the xaml.
I tried implementing a DataTrigger and after an hour removed the code because it was not working. It would not recognise my field name. Does anyone have a very simple guide to how to do this or what would be the best approach?
As you apparently are not dealing with fields after all, this style should do what you want:
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsActive}" Value="True">
<Setter Property="Foreground" Value="Navy"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
It would not recognise my field name.
You cannot bind to fields, end of story.

ListBoxItem selection on TextBox focus

I have a ListBox showing items using the following DataTemplate:
<DataTemplate x:Key="PersonTemplate" DataType="{x:Type DAL:ResultItem}" >
<StackPanel Width="280" >
<TextBox BorderThickness="0" IsReadOnly="True" Background="Transparent" Text="{Binding FullName1, Mode=OneWay}"/>
...
</StackPanel>
</DataTemplate>
I am using a transparent, read-only, borderless TextBox as opposed to a TextBlock because I want users to be able to select the text for copying. Should I do it differently?
How can I write this so that when the user clicks on the TextBox, the ListBoxItem gets selected as well?
Thanks!
I found that the answer is just to do this from the ListBoxItem standpoint, adding the following to its DataTemplate:
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True"/>
</Trigger>
</Style.Triggers>

Resources