WPF datagrid row details peek (layers) - wpf

i am looking for a way to quickly peek into collapsed row details in DataGrid.
when a user mouses over the rows, there should be a quick peek layer next to the cursor that would have a summary of what is in details. Ultra fast is key here.
looking for something equivalent to layered div in DHTML. No transparency effects needed.
From what i've seen on this forum, this is not inherently supported? i'd need to show a separate window?

Why not use ToolTip property of the row?
<DataGrid Name="_grid">
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<TextBlock Text="{Binding Item3}" />
</DataTemplate>
</DataGrid.RowDetailsTemplate>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="ToolTip">
<Setter.Value>
<TextBlock Text="{Binding Item3}" />
</Setter.Value>
</Setter>
</Style>
</DataGrid.RowStyle>
</DataGrid>
...where Item3 is a property you want to display (I used a simple Tuple as ItemsSource). You'll probably have more complicated content of DataTemplate and ToolTip of course but this should give you an idea.

Related

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

sort of special accordion like control

I have put an example link in here:
http://activeden.net/item/xml-horizontal-vertical-accordion-banner-rotator/full_screen_preview/127714?ref=premiumtemplates
I try to achieve something similar (but far more basic) with WPF.
Not the flying text stuff, only the basic navigation idea.
I tried to build it with some expander controls and a stackpanel.
What I came up with is this:
<ItemsControl Grid.Row="1" IsTabStop="False" ItemsSource="{Binding Path=tabs,Mode=OneWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
I use MVVM, so there is also a template which is applied:
<DataTemplate DataType="{x:Type vm:TabulatorViewModel}">
<Expander HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ExpandDirection="{Binding .direction,Mode=OneWay}" IsExpanded="{Binding .isExpanded,Mode=TwoWay}" Header="{Binding .header,Mode=OneWay}" >
<Expander.Style>
<Style TargetType="{x:Type Control}">
<Setter Property="Template" Value="{StaticResource HorizontalExpanderRight}" />
<Style.Triggers>
<DataTrigger Binding="{Binding .direction}" Value="Left">
<Setter Property="Template" Value="{StaticResource HorizontalExpanderLeft}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Expander.Style>
<StackPanel>
<Label Content="{Binding .seitenInhalt.Header,Mode=OneWay}"></Label>
<TextBox Text="{Binding .seitenInhalt.Inhalt,Mode=OneWay}"></TextBox>
<Button Content="zurück" Command="{Binding .seitenInhalt.MovePreviousCommand}" />
<Button Content="vor" Command="{Binding .seitenInhalt.MoveNextCommand}"/>
</StackPanel>
</Expander>
</DataTemplate>
So, this is working, at least kind of.
two screenshots from my current project to explain the issues:
Could not post picture because of reputation points.
All Items together should use the complete width of the stackpanel, not like in the picture. Could not post picture because of reputation points.
All items should use the complete width, but the one expanded item should have a bigger width then the rest. As on the picture, but the collapsed items should use the remaining space, each by the same amount filling the gap)
Any help would be great, I hope it is possible to understand my goal / issues.
I think what you want to use is a UniformGridPanel or WrapPanel, which will use the full width available, rather than a StackPanel which is made to use the minimum width possible. The panel overview is here.
You'll probably want to use a Grid with the Height/Width of the Columns/Rows set to * if the item is Expanded, or Auto if not.
Also, if you're using a Grid in an ItemsControl, you need to set the Grid.Row/Grid.Column, and Width/Height properties on the ContentPresenter, not the ItemTemplate since the ItemTemplate in a ItemsControl is always wrapped in a ContentPresenter.

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.

Always show WPF TextBox Tooltip

Is it possible to display tooltip constantly, not depending on whether the control is focused ot not, but depending only on the value of the bind property.
<TextBox Name="projectTextBox"
ToolTipService.Placement="Bottom" ToolTipService.ShowDuration="12000"
MinWidth="150" Text="{Binding ProjectName}" IsEnabled="{Binding IsEnabled}">
<TextBox.ToolTip>
<ToolTip Placement="Bottom"
StaysOpen="True" Content="TEXT"
Visibility="{Binding IsNotFound, Converter={StaticResource booleanToVisibilityCollapsedConverter}}"
IsOpen="True">
</ToolTip>
</TextBox.ToolTip>
</TextBox>
you should use an adorner for the behavior you are looking for. you can use a datatrigger or what you want to show the adorner as long as you want. btw with an adorner you did not have the problems popups have, while moving the mainwindow.
Why not set the tooltip based on a trigger?
<TextBox Name="projectTextBox" ToolTipService.Placement="Bottom" ToolTipService.ShowDuration="12000" MinWidth="150" Text="{Binding ProjectName}" IsEnabled="{Binding IsEnabled}">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsNotFound}" Value="False">
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip Placement="Bottom" StaysOpen="True" Content="TEXT" IsOpen="True" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
Basically, you cannot force the tooltip to be shown constantly, because Windows is the one who decides when the tooltip hides (usually on MouseLeave or after some amount of time) to keep the look and feel of the applications consistent (The tooltip control is made to act this way).
If you want to display some helpful information to the user in a way that differs from the standard Windows tooltip way, you should consider using something else than a ToolTip, maybe a Popup or something similar with the FormNotification control from this article.
You can consider using Popup instead. Or if you are using material design for WPF, you can consider using PopupBox.
I know I late for the party this time.

Storyboard for a DataTemplate element in 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>

Resources