I am trying to implement a TreeView inside my ListView.
I would like the backgroud of my TreeBox would be the same as its "Father" row.
I guess there is a possibility to bind its BackGround property to its row's BackGround property, but how to do that?
Here is an image to explain the issue :
1st line is selected
2nd line is Over
I also put my XAML, in case that would help :
<ListView x:Name="ListView4" SelectedItem="{Binding SelectedRepere}" ItemsSource="{Binding ListeDesReperes}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="4" MouseDoubleClick="ListView_MouseDoubleClick" GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler" ContextMenuOpening="ListView4_ContextMenuOpening" SelectionChanged="ListView4_SelectionChanged" Visibility="{Binding Grid4Visible, Converter={StaticResource BoolToVisConverter}}" >
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsUniqueGeometry}" Value="true">
<Setter Property="FontWeight" Value="Bold" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
<ListView.ContextMenu>
<ContextMenu x:Name="Context4">
<MenuItem x:Name="Context4MakeLonger" Header="{x:Static p:Resources.MakeLonger}" Click="Make_Longer"/>
<MenuItem x:Name="Context4Distinguer" Header="{x:Static p:Resources.DistributeToAss}" Click="DistinguerDetailRepere"/>
<MenuItem x:Name="Context4Search" Header="{x:Static p:Resources.Search}" Click="Search_Detail"/>
</ContextMenu>
</ListView.ContextMenu>
<ListView.View>
<GridView AllowsColumnReorder="true" x:Name="GridView4">
<GridViewColumn DisplayMemberBinding="{Binding Path=ID}" Header="ID" Width="200"/>
<GridViewColumn Header="Name">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<TreeView BorderThickness="0" x:Name="treeviewList" ItemsSource="{Binding RepereTree}" Width="Auto">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<DataTemplate>
<TreeViewItem ItemsSource="{Binding ListeSubReperes}">
<TreeViewItem.Header>
<Grid>
<TextBlock Foreground="#FF042271" Text="{Binding NameOri}" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Column="0" Tag="{Binding Name}" MouseMove="mouseOverNameRepere" ToolTip="{Binding Path=ToolTipModifications}" MouseDown="TreeView_Main_Click"/>
</Grid>
</TreeViewItem.Header>
<TreeViewItem.ItemTemplate>
<DataTemplate>
<Grid Margin="-20,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Foreground="#FF042271" Text="{Binding Name}" Tag="{Binding IdRepereOri}" Margin="10,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Column="0"MouseDown="TreeView_Sub_Click"/>
</Grid>
</DataTemplate>
</TreeViewItem.ItemTemplate>
</TreeViewItem>
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
...
Edit :
Finally, putting "transparent doesn't completely solve the proble, sometimes it works, but sometimes when selecting the Treeview, it seems it gets selected, and I have the following result :
Then when I unselect it, it gives that result :
I would like the Treeview would be as any element of my row, for this the only way I found is add on each TextBlock a MouseDown event, then I do this :
private void TreeView_Main_Click(object sender, MouseButtonEventArgs e)
{
TextBlock item = (TextBlock)sender;
string name = (string)item.Text;
Repere rep = contexte.ListeDesReperes.FirstOrDefault(x => x.Name == name);
if (rep != null)
{
contexte.SelectedRepere = rep;
}
}
private void TreeView_Sub_Click(object sender, MouseButtonEventArgs e)
{
TextBlock item = (TextBlock)sender;
long idOri = (long)item.Tag;
Repere rep = contexte.ListeDesReperes.FirstOrDefault(x => x.ID==idOri);
if (rep != null)
{
contexte.SelectedRepere = rep;
}
}
Don't know if there is an easier way to do that, but that's all what I found until now.
Try to set the Background property of the TreeView to Transparent:
<TreeView Background="Transparent">
I put it here for who would come here :
how to change highlight values
Here it is well explained what are SystemColors parameters, on the end just had to add :
<TreeView.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey }" Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
</TreeView.Resources>
Related
So I have the following problem :
In my ListView, I want to add ToolTips to specific GridViewColumns.
Sometimes these ToolTips are empty, and I need to hide them.
When I have a ToolTip on a ListView Line, I encounter no problem doing the following in my App.xaml file:
<Style TargetType="ToolTip">
<Style.Triggers>
<Trigger Property="Content" Value="{x:Static sys:String.Empty}">
<Setter Property="Visibility" Value="Collapsed" />
</Trigger>
<Trigger Property="Content" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed" />
</Trigger>
</Style.Triggers>
</Style>
But in the case a ToolTip is applied to only one column of my ListView, my XAML is the following :
<GridViewColumn Header="{x:Static p:Resources.Name}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Path=Name}" Tag="{Binding Name}"
MouseMove="mouseOverNameRepere">
<TextBlock.ToolTip>
<StackPanel>
<Grid>
<TextBlock Grid.Column="0"
Text="{Binding Path=ToolTipModifications}"
TextAlignment="Left" HorizontalAlignment="Left"/>
</Grid>
</StackPanel>
</TextBlock.ToolTip>
</TextBlock>
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
How can I hide the ToolTip when it is empty? The code in my App.xaml is not working.
Also tried to do it in code behind :
TextBlock item = (TextBlock)sender;
ToolTip toolTip = (ToolTip)item.ToolTip;
But second line gives me an exception as item.ToolTip is a StackPanel object and cannot be converted?
In fact I calculate the ToolTip content only when I enter the TextBox element, so I thought I would then check and apply toolTip.Visibility at this moment, but I couldn't.
Your Style should work if you set the ToolTip property of the TextBlock like this:
<TextBlock Text="{Binding Path=Name}" Tag="{Binding Name}" MouseMove="mouseOverNameRepere"
ToolTip="{Binding Path=ToolTipModifications}" />
Use Rectangle instead of Tooltip
<GridViewColumn Header="{x:Static p:Resources.Name}" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Path=Name}" Tag="{Binding Name}"/>
<Rectangle Fill="Transparent" ToolTipService.ToolTip="{Binding Path=ToolTipModifications}" MouseEnter="UIElement_OnMouseEnter"/>
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
Then check if ToolTipModifications is empty in MouseEnter event
private void UIElement_OnMouseEnter(object sender, MouseEventArgs e)
{
if (sender is Rectangle rectangle)
{
if (string.IsNullOrEmpty(rectangle.ToolTip.ToString()))
{
rectangle.Visibility = Visibility.Collapsed;
}
}
}
Please try this code:
<DataGridTextColumn Width="200" Binding="{Binding Name}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource TextBlockDefaultStyle}">
<Setter Property="ToolTip" Value="{Binding Name}">
<Setter Property="ToolTipService.ShowDuration" Value="6000">
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
I want to display a List in a ListView with Master Detail View. The Master View works fine, but the binding to the detail view is not working. What am i doing wrong?
Code Behind:
DataContext = new VirtualizingCollection<LinesSummary>(fs, 100)
LinesSummary Class:
public class LinesSummary {
public string dateString { get; set; }
}
XAML:
<StackPanel>
<ListView Margin="5" Style="{DynamicResource lvStyle}" Height="200" x:Name="Master"/>
<ListView Margin="5" Style="{DynamicResource lvStyle_Detail}" Height="200" x:Name="Detail"/>
</StackPanel>
Dynamic Resource for Master View:
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
<Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling"/>
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="True"/>
<Setter Property="ListView.ItemsSource" Value="{Binding}"/>
<Setter Property="ListView.View">
<Setter.Value>
<GridView>
<GridViewColumn Header="Date" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding dateString}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</Setter.Value>
</Setter>
</Style>
Dynamic Resource for Detail View:
<Style x:Key="lvStyle_Detail" TargetType="{x:Type ListView}">
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
<Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling"/>
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="True"/>
<Setter Property="ListView.ItemsSource" Value="{Binding ElementName=Master, Path=SelectedItem.LinesSummary}"/>
<Setter Property="ListView.View">
<Setter.Value>
<GridView>
<GridViewColumn Header="aaa" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding dateString}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</Setter.Value>
</Setter>
</Style>
The ItemsSource of a ListView can only be bound to an IEnumerable so even if you bind the ItemsSource property of the second ListView like this it won't work:
ItemsSource="{Binding ElementName=Master, Path=SelectedItem}"
...because LinesSummary is not an IEnumerable.
Since there is only a maximum of one item selected in Master, you might as well bind a TextBlock to the dateString property of its SelectedItem:
<StackPanel>
<ListView Margin="5" Style="{DynamicResource lvStyle}" Height="200" x:Name="Master"/>
<ListView Margin="5" Style="{DynamicResource lvStyle_Detail}" Height="200" x:Name="Detail">
<ListViewItem>
<TextBlock Text="{Binding Path=SelectedItem.dateString, ElementName=Master}" />
</ListViewItem>
</ListView>
</StackPanel>
Remove this setter from the lvStyle_Detail:
<Setter Property="ListView.ItemsSource" Value="{Binding ElementName=Master, Path=SelectedItem.LinesSummary}"/>
I am working with a Wpf/XAML based application which has DataGrid with one of the DataGridColumn containing the TreeView control to let user select the item required.
<DataGrid.Columns>
<DataGridTextColumn Header="SerialNumber" Width="*" Binding="{Binding SerialNumber}" />
<DataGridTemplateColumn Header="Field" Width="*">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<uControls:FieldTreeViewControl />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding CurrentField.FieldName,Mode=TwoWay}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Field column in above code is the one which displays treeviewcontrol in the DataGrid cell by referencing the FieldTreeViewControl and it works perfectly. The xaml code of FieldTreeViewControl is :
<UserControl>
.......
<Grid>
<TreeView x:Name="MyUITreeView" ItemsSource="{Binding Fields}">
<TreeView.Resources>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsNodeExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsNodeSelected, Mode=TwoWay}" />
</Style>
<DataTemplate x:Key="NormalTemplate">
<StackPanel Orientation="Horizontal">
<!--<TextBlock Text="-" Margin="3"/>-->
<TextBlock Text="{Binding FieldName}" Margin="3"/>
<StackPanel.ContextMenu>
<ContextMenu Name="myChildMenu" DataContext="{Binding PlacementTarget,RelativeSource={RelativeSource Self}}">
<MenuItem Header="Add Field" Command="{Binding DataContext.AddFieldCommand}" CommandParameter="{Binding}">
</MenuItem>
</ContextMenu>
</StackPanel.ContextMenu>
</StackPanel>
</DataTemplate>
<!--<DataTemplate x:Key="EditTemplate">
<TextBox Text="{Binding FieldName}"/>
</DataTemplate>-->
</TreeView.Resources>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<ContentPresenter Content="{Binding}">
<ContentPresenter.Style>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="ContentTemplate" Value="{StaticResource NormalTemplate}"/>
<Style.Triggers>
<DataTrigger
Binding="{Binding IsNodeSelected,
RelativeSource={RelativeSource
FindAncestor,
AncestorType={x:Type TreeViewItem}}}"
Value="True">
</DataTrigger>
</Style.Triggers>
</Style>
</ContentPresenter.Style>
</ContentPresenter>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
Now when user completes selecting an item from treeview I want to collapse treeview to show only that selected item. Later when user wants to change his selection , then the treeview should be available again by clicking on that column/cell. Is that possible to do this in wpf/XAML ? I tried to follow the link but not able to implement it for my scenario.
I have this XAML form with a virtualized ListView to show a grid:
<Window x:Class="WpfVirtualList.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="lvStyle" TargetType="{x:Type ListView}">
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
<Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling"/>
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="True"/>
<Setter Property="ListView.ItemsSource" Value="{Binding}"/>
<Setter Property="ListView.View">
<Setter.Value>
<GridView>
<GridViewColumn Header="Cups" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding CUPS}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="MeterId" Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding MeterID}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Matricula" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding MatriculaCT}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsLoading}" Value="True">
<Setter Property="ListView.Cursor" Value="Wait"/>
<Setter Property="ListView.Background" Value="LightGray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<ListView x:Name="lv" HorizontalContentAlignment="Stretch" Style="{DynamicResource lvStyle}" SelectionChanged="lv_SelectionChanged" />
</Grid>
</Window>
And when I select an item everything works OK...
But when I select a second item the system throws an StackOverflow... and I don't know why.
I have breakpoints in all the virtual list methods, but no one of them are called when I click on the second item.
I have a breakpoint in SelectionChanged event, and isn't called either.
//CUPS is the id
private void lv_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if(e.RemovedItems.Count > 0)
Debug.WriteLine("selected: "+((ItemClass)e.RemovedItems[0]).CUPS);
if(e.AddedItems.Count > 0)
Debug.WriteLine("unselected: " + ((ItemClass)e.AddedItems[0]).CUPS);
}
I fixed it controlling the GotFocus event and unselecting all... but this is not the way to solve this.
private void lv_GotFocus(object sender, RoutedEventArgs e)
{
lv.UnselectAll();
}
My Listview items are not stretching to the full width of the column. There is always a margin on the right of my cell border. I would like to get the bordered area to stretch over the full column width and get rid of any padding, margins or anything else on the left and right of my content. The goal is to have the borders fill the whole space in each cell.
I have already applied stretching and set the margins to "-6,0,-6,0" but that doesn't seem to solve the problem.
Here is my code:
<Grid>
<Grid.Resources>
<x:Array Type="{x:Type sys:String}" x:Key="items">
<sys:String>Foo</sys:String>
<sys:String>Bar</sys:String>
<sys:String>Spong</sys:String>
</x:Array>
</Grid.Resources>
<ListView ItemsSource="{StaticResource items}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Margin"
Value="-6, 0,-6,0" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Data" Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Border BorderThickness="2" BorderBrush="Black" HorizontalAlignment="Stretch">
<TextBox Text="{Binding .}" />
</Border>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Length"
DisplayMemberBinding="{Binding Length}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
I got it working using a DataTemplate resource and setting the border's margin to -6.
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<x:Array Type="{x:Type sys:String}" x:Key="items">
<sys:String>Foo</sys:String>
<sys:String>Bar</sys:String>
<sys:String>Spong</sys:String>
</x:Array>
<DataTemplate x:Key="MyDataTemplate">
<Border BorderThickness="2" BorderBrush="Black" Margin="-6">
<TextBox Text="{Binding .}" Margin="0" Padding="0"/>
</Border>
</DataTemplate>
</Grid.Resources>
<ListView ItemsSource="{StaticResource items}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView >
<GridViewColumn Header="Data" Width="80" CellTemplate="{StaticResource MyDataTemplate}" />
<GridViewColumn Header="Length" DisplayMemberBinding="{Binding Length}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
Just set the Margin for your Border element:
<Border Margin="-6,0,-6,0" BorderThickness="2" BorderBrush="Black" HorizontalAlignment="Stretch">
<TextBox Text="{Binding .}" />
</Border>
Alternative solution
typeof(GridViewRowPresenter).GetField("_defalutCellMargin", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.GetField).SetValue(null, new Thickness(0));
I do it with
HorizontalContentAlignment="Stretch"
on ListView