In an WPF ListView I have ListViewItems that consist of two columns, one column is a TextBlock and the another one contains two buttons (Edit and Delete) in the same column.
Also the first row of the WPF listView contains a button for adding new ListViewItems to the ListView. This first row is only for this purpose.
I have followed the example explained here. I have adapted it to my model but it is exactly the same.
Below the DataTemplate defined in the resources and later applied to the ListView:
<DataTemplate x:Key="FirstRowTemplate1">
<Grid Width="190">
<Button Content="Add" Command="{Binding Path=DataContext.AddCommand, ElementName=MyListView}"
Width="180"
HorizontalAlignment="Center"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="NextRowTemplate1">
<TextBlock Text="{Binding PathString}"/>
</DataTemplate>
<DataTemplate x:Key="NameColumnTemplate">
<ContentPresenter x:Name="ButtonPresenter"
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}"
ContentTemplate="{StaticResource NextRowTemplate1}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Add}" Value="True">
<Setter TargetName="ButtonPresenter"
Property="ContentTemplate"
Value="{StaticResource FirstRowTemplate1}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Add}" Value="False">
<Setter TargetName="ButtonPresenter"
Property="ContentTemplate"
Value="{StaticResource NextRowTemplate1}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<DataTemplate x:Key="FirstRowTemplate2"/>
<DataTemplate x:Key="NextRowTemplate2">
<StackPanel Orientation="Horizontal">
<Button Content="Edit" Command="{Binding Path=DataContext.EditCommand, ElementName=MyListView}" CommandParameter="{Binding PathString}"/>
<Button Content="-" Command="{Binding Path=DataContext.DelCommand, ElementName=MyListView}" Margin="10 0 0 0" CommandParameter="{Binding PathString}"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="AddDelItemTemplate">
<ContentPresenter x:Name="ButtonPresenter"
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}"
ContentTemplate="{StaticResource NextRowTemplate2}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Add}" Value="True">
<Setter TargetName="ButtonPresenter"
Property="ContentTemplate"
Value="{StaticResource FirstRowTemplate2}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Add}" Value="False">
<Setter TargetName="ButtonPresenter"
Property="ContentTemplate"
Value="{StaticResource NextRowTemplate2}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
Then they are applied to the ListView:
<ListView x:Name="MyListView"
ItemsSource="{Binding pathList}"
IsSynchronizedWithCurrentItem="True">
<ListView.View>
<GridView>
<GridViewColumn Header="Paths" Width="350" CellTemplate="{StaticResource NameColumnTemplate}"/>
<GridViewColumn Width="70" Header="Edit/Delete" CellTemplate="{StaticResource AddDelItemTemplate}"/>
</GridView>
</ListView.View>
</ListView>
Now I am trying to perform an inline edit for the TextBlock once "Edit" button is clicked for this ListViewItem and exit edition mode once user validates it by pressing return key. If user press ESC key on edit mode, it should be exit edit mode and keep the value previous editing.How can I do this?
Related
My ListView contains a textbox per column to change data. Via Style my Listview rows are colored in different colors depending on the alternation index.
I want my textboxes within the listview to look like the entire line.
Actually its like this:
The lines should cover the textboxes.
The Code to color the ListView Rows:
<Style x:Key="DifAlternationColorsLV" TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="#FFB1E4EF"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="#FFD4EBFF"></Setter>
</Trigger>
</Style.Triggers>
</Style>
The code in the XAML of the View:
<Border Grid.Row="1" Grid.Column="0"
Margin="10,10,10,10"
BorderBrush="#FF474A57"
CornerRadius="10,10,10,10"
BorderThickness="2,2,2,2"
Width="300"
MaxHeight="200"
Background="White">
<StackPanel Margin="0,0,0,20" Orientation="Vertical">
<StackPanel Grid.Column="0" Grid.RowSpan="1"
Grid.Row="1"
VerticalAlignment="Top">
<Label HorizontalAlignment="Center" FontWeight="Bold">
Schichten
</Label>
<ListView x:Name="Shift" MinHeight="150" MaxHeight="150" MinWidth="250" HorizontalContentAlignment="Stretch" HorizontalAlignment="Center"
IsSynchronizedWithCurrentItem="True"
ItemContainerStyle="{StaticResource DifAlternationColorsLV}"
AlternationCount="2"
ItemsSource="{Binding UiShiftHModelList, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedLine, UpdateSourceTrigger=PropertyChanged}" d:ItemsSource="{d:SampleData ItemCount=3}">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="Bezeichnung" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox x:Name="Bezeichnung" MinWidth="100"
Style="{StaticResource TBoxInListV}"
Text="{Binding Bezeichnung, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
BorderThickness="0">
</TextBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Tagmuster" Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<!---->
<TextBox x:Name="Tagmuster" MinWidth="80"
Background="{Binding ElementName=Shift}"
Style="{StaticResource TBoxInListV}"
Text="{Binding TagmusterID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
BorderThickness="0">
</TextBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Edit" Width="40">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button x:Name="SaveShiftH"
Style="{StaticResource BtnListSave}"
Grid.Column="0">
</Button>
<Button x:Name="UpdateShiftH"
Style="{StaticResource BtnListUpdate}"
Grid.Column="0">
</Button>
<Button x:Name="DeleteShiftH"
Style="{StaticResource BtnListDelete}"
Grid.Column="1">
</Button>
<Button x:Name="ReopenShiftH"
Style="{StaticResource BtnListReopen}"
Grid.Column="0">
</Button>
</Grid>
</StackPanel>
<DataTemplate.Triggers>
<!--Visibility of the Buttons-->
<DataTrigger Binding="{Binding EditModus}" Value="0">
<Setter TargetName="SaveShiftH" Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding EditModus}" Value="2">
<Setter TargetName="UpdateShiftH" Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding EditModus}" Value="1">
<Setter TargetName="UpdateShiftH" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding EditModus}" Value="2">
<Setter TargetName="DeleteShiftH" Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding EditModus}" Value="1">
<Setter TargetName="DeleteShiftH" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<!--<DataTrigger Binding="{Binding EditModus}" Value="0">
<Setter TargetName="Delete" Property="Visibility" Value="Collapsed"/>
</DataTrigger>-->
<DataTrigger Binding="{Binding EditModus}" Value="1">
<Setter TargetName="ReopenShiftH" Property="Visibility" Value="Visible"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
</StackPanel>
</Border>
If I change the Background Binding from the Textbox to:
Background="{Binding ElementName=Shift}"
The Line appears exactly I want it to but leads to a lot binding errors.
Any ideas?
You can make the background of the TextBox wholly or partially transparent; that will make the background of the row visible:
<TextBox x:Name="Bezeichnung" MinWidth="100" Background="#60FFFFFF"
Style="{StaticResource TBoxInListV}"
Text="{Binding Bezeichnung, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
BorderThickness="0">
</TextBox>
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 have a listview with buttons for each row, but when I bind the IsEnabled property to the SelectedIndex still keep enable all the buttons, I just need this one, and also I have another button that has to be enable depends on the property of the object in the listview.
e.g I have a class File that has a property bool HasLckFile, and I need that the download button keep disable until the user upload, but the binding is not working.
XAML:
<ListView x:Name="lv" Style="{StaticResource CustomListViewStyle}" Margin="470,0,0,0" SelectionMode="Multiple" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" >
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Tag="{Binding Filename}" IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListViewItem}}, Path=IsSelected}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="150">
<GridViewColumn DisplayMemberBinding="{Binding Filename}"/>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="download" VerticalAlignment="Center" Click="btnDownload">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=lv, Path=SelectedIndex}" Value="-1">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="upload" VerticalAlignment="Center" Click="btnUpload">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=lv, Path=SelectedIndex}" Value="-1">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
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 made UserControl of DataGrid. I placed this new component into page1.xaml. I would like to use some template and setting based on value in Data1.
Could you help me with this code how to avoid the error message?
<my:MyDataGrid Grid.Column="1" Grid.Row="1" HorizontalAlignment="Left" Margin="29,295,0,0" Name="myDataGrid1"
VerticalAlignment="Top" Height="151" Width="176" SelectionChanged="myDataGrid1_SelectionChanged">
<my:MyDataGrid.Columns>
<DataGridTemplateColumn Header="Col1" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Data1}" x:Name="mytext" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Data1}" Value="1">
<Setter TargetName="mytext" Property="Foreground" Value="Red" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</my:MyDataGrid.Columns>
</my:MyDataGrid>
I got error message:
Cannot set Name attribute value 'mytext' on element 'TextBlock'.
'TextBlock' is under the scope of element 'MyDataGrid', which already
had a name registered when it was defined in another scope.
You can add you data trigger to a style attached to a TextBlock
<my:MyDataGrid Grid.Column="1" Grid.Row="1" ...>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Col1" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Data1}" x:Name="mytext">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Data1}" Value="1">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</my:MyDataGrid>