Multiple lines of text in ListView - c#

I'm trying to get multiple lines in a listView I currently have the following XAML:
<ListView x:Name="listTasks" Margin="0,0,1.5,0" Background="{x:Null}" BorderBrush="{x:Null}" BorderThickness="0" Foreground="White" ItemsSource="{Binding TasksCollection}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<Trigger Property="IsSelected"
Value="True">
<Setter Property="Background"
Value="{x:Null}" />
<Setter Property="BorderBrush"
Value="{x:Null}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Background"
Value="{x:Null}" />
<Setter Property="BorderBrush"
Value="{x:Null}" />
</Trigger>
</Style.Triggers>
<Setter Property="Height" Value="50px" />
<Setter Property="Focusable" Value="false" />
</Style>
</ListView.ItemContainerStyle>
<ListView.Resources>
<Style x:Key="CustomHeaderStyle" TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="Visibility" Value="Collapsed" />
</Style>
</ListView.Resources>
<ListView.View>
<GridView ColumnHeaderContainerStyle="{DynamicResource CustomHeaderStyle}">
<GridViewColumn Header="">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat=" Module: {0} Conditions: {1}|{2}|{3} for {4} minutes">
<Binding Path="Module"/>
<Binding Path="FirstValue"/>
<Binding Path="SecondValue"/>
<Binding Path="ThirdValue"/>
<Binding Path="Minutes"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
This outputs something like:
What I am trying to achieve is something like this (ignore the different colored background):
I can't seem to bring my head around how I would do this, any ideas?
Thanks

You can use a vertical StackPanel in order to put a series of TextBlock elements one on top of another:
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Module, StringFormat='Module: {0}'}"/>
<TextBlock Text="{Binding FirstValue, StringFormat='Module: {0}'}"/>
...
</StackPanel>
</DataTemplate>
Or you can format everything in one `TextBlock':
<DataTemplate>
<TextBlock>
<Run Text="Module: "/><Run Text="{Binding Module}"/><LineBreak/><Run Text="Conditions: "/><Run Text="{Binding FirstValue}"/><LineBreak/>
...
</TextBlock>
</DataTemplate>

Related

WPF INotifyDataErrorInfo highlight ListBoxItem

I've got a ListBox as such:
<ListBox Margin="5" ItemsSource="{Binding NetworkAdapters, Mode=OneWay}" SelectedItem="{Binding SelectedNetworkAdapter}" SelectionChanged="{s:Action SelectedNetworkAdapterChanged}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="2" VerticalAlignment="Top"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Ellipse Width="15" Height="15" Margin="5">
<Ellipse.Style>
<Style TargetType="Ellipse">
<Setter Property="Fill" Value="Gray"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Status}" Value="{x:Static wpf:NetworkAdapterStatus.Up}">
<Setter Property="Fill" Value="Green"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Status}" Value="{x:Static wpf:NetworkAdapterStatus.Down}">
<Setter Property="Fill" Value="Red"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<StackPanel Margin="5,0,0,0">
<TextBlock Text="{Binding Name}" FontWeight="Bold"/>
<TextBlock Text="{Binding Description}"></TextBlock>
<TextBlock Text="{Binding Speed, StringFormat='Speed: {0}'}" FontSize="10"/>
<TextBlock Text="{Binding Status}" FontSize="10"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
NetworkAdapters is a collection of View Models that implement INotifyDataErrorInfo.
With the current XAML, if there is an error in any of the View Models the whole ListBox will be highlighted red, but I would like just the single ListBoxItems that contains errors to be highlighted.
I had a look at similar questions such as:
WPF ListBox ErrorTemplate and
Validating a ListBoxItem rather than a ListBox
But I still can't make this work. Any help would be appreciated.
UPDATE:
As per Krzysztof's advice, I tried wrapping the StackPanel around a border and using a DataTrigger as such:
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1">
<Border.Resources>
<Style TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding HasErrors}" Value="True">
<Setter Property="BorderBrush" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Resources>
<StackPanel> ... </StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
However, what this produces is the following:
Which is slightly different from what I expected. I would like to have the highlight around the whole ListBoxItem not just part of it as per the image.
You need to implement an ItemContainerStyle as below:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="Transparent" />
<Style.Triggers>
<DataTrigger Binding="{Binding Validation.HasErrors}" Value="True">
<Setter Property="BorderBrush" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
This will enable you to change the border of the ListBoxItem itself, so the whole things as you want.
You can forget about ErrorTemplate and just use DataTrigger to bind to Validation.HasErrors:
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type StackPanel}" BasedOn="{StaticResource {x:Type StackPanel}}">
<Style.Triggers>
<DataTrigger Binding="{Binding Validation.HasErrors}" Value="True"> <!-- change all text to red -->
<Setter Property="Foreground" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
</StackPanel>
If you want a highlight, you can wrap StackPanel with a Border and set its color to red in a style.

How to bind text alignment in GridViewColumn

I'm using MVVM in a WPF application. I've a UserControl whose DataContext is set to a ViewModel. The UserControl is a table with 3 columns.
This is the following ListView/GridView:
<DockPanel>
<ListView DockPanel.Dock="Top" ItemsSource="{Binding Items}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ctrl:ListViewLayoutManager.Enabled="True">
<ListView.View>
<GridView>
<GridViewColumn Header="{Binding ColumnHeader1}"
CellTemplate="{StaticResource cellTemplateColumn1}">
<GridViewColumn.HeaderContainerStyle>
<Style BasedOn="{StaticResource {x:Type GridViewColumnHeader}}" TargetType="GridViewColumnHeader">
<Setter Property="TextBlock.TextAlignment" Value="{Binding Column1HAlignment}" />
</Style>
</GridViewColumn.HeaderContainerStyle>
</GridViewColumn>
<GridViewColumn Header="{Binding ColumnHeader2}"
CellTemplate="{StaticResource cellTemplateColumn2}">
<GridViewColumn.HeaderContainerStyle>
<Style BasedOn="{StaticResource {x:Type GridViewColumnHeader}}" TargetType="GridViewColumnHeader">
<Setter Property="TextBlock.TextAlignment" Value="{Binding Column2HAlignment}" />
</Style>
</GridViewColumn.HeaderContainerStyle>
</GridViewColumn>
<GridViewColumn Header="{Binding ColumnHeader3}"
CellTemplate="{StaticResource cellTemplateColumn3}"
ctrl:RangeColumn.IsFillColumn="True">
<GridViewColumn.HeaderContainerStyle>
<Style BasedOn="{StaticResource {x:Type GridViewColumnHeader}}" TargetType="GridViewColumnHeader">
<Setter Property="TextBlock.TextAlignment" Value="{Binding Column3HAlignment}" />
</Style>
</GridViewColumn.HeaderContainerStyle>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</DockPanel>
This is achieved by the following resources:
<Style TargetType="GridViewColumnHeader">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewColumnHeader">
<TextBlock Text="{TemplateBinding Content}" Margin="5" Width="{TemplateBinding Width}">
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="FontSize" Value="14" />
</Style>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
<DataTemplate x:Key="cellTemplateColumn1">
<fa:ImageAwesome Icon="{Binding IconType}" Foreground="{Binding Status}" Width="10" />
</DataTemplate>
<DataTemplate x:Key="cellTemplateColumn2">
<TextBlock Text="{Binding SerialNumber, StringFormat='0'}" />
</DataTemplate>
<DataTemplate x:Key="cellTemplateColumn3">
<TextBlock Text="{Binding Action}" TextWrapping="Wrap" />
</DataTemplate>
The text alignments of each column is settable through the view model. I can do this easily for the headers:
<GridViewColumn.HeaderContainerStyle>
<Style BasedOn="{StaticResource {x:Type GridViewColumnHeader}}" TargetType="GridViewColumnHeader">
<Setter Property="TextBlock.TextAlignment" Value="{Binding Column1HAlignment}" />
</Style>
</GridViewColumn.HeaderContainerStyle>
But how can I pass the same parameter (Column1HAlignment) to align the cell's TextBlock contents?
Note the alignment of the 2nd column (where header is #) in the image above. The header is right aligned through data binding. I want the same binding for each cell content.
You could bind the HorizontalAlignment property of the element in the CellTemplate to the Column1HAlignment source property using a {RelativeSource}:
<DataTemplate x:Key="cellTemplateColumn2">
<TextBlock Text="{Binding SerialNumber, StringFormat='0'}"
HorizontalAlignment="{Binding DataContext.Column1HAlignment,
RelativeSource={RelativeSource AncestorType=ListView}}"/>
</DataTemplate>

WPF DataGrid Grouped Rows in Expander adds extra column on right side, disappears when all expanders are closed

Another WPF DataGrid-related question.
I have a DataGrid whose rows are grouped, and each group is underneath an Expander control. There are two columns per row. By default, I have all the expanders opened. The second column's width is set to "*", and row headers have already been turned off.
When I close all the expanders, the layout changes the tiniest bit, shifting the expander controls to the left a little. When I open any one of the expanders, they shift the tiniest bit to the right. I also notice that when an expander is open, the column headers show an additional column on the right side, which makes the horizontal scroll bar appear.
How can I adjust the datagrid declaration to make this additional column not exist/appear when an expander is open?
<Grid>
<ScrollViewer VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled" >
<DataGrid AutoGenerateColumns="False"
ItemsSource="{Binding Path=MyCollection}"
GridLinesVisibility="None"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
CanUserSortColumns="False"
CanUserResizeColumns="False"
CanUserResizeRows="False"
HeadersVisibility="Column">
<DataGrid.Resources>
<ResourceDictionary>
<Style x:Key="{x:Type DataGridCell}" TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="BorderBrush" Value="{x:Null}" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="{x:Type DataGridRow}" TargetType="{x:Type DataGridRow}">
<Setter Property="Margin" Value="4" />
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="BorderBrush" Value="{x:Null}" />
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</DataGrid.Resources>
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<DataGridRowsPresenter />
</ItemsPanelTemplate>
</GroupStyle.Panel>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander Margin="4"
IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal"
Margin="4">
<TextBlock FontWeight="Bold"
FontSize="14"
Text="{Binding Path=Name}" />
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTemplateColumn Width="Auto">
...
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="*">
...
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</ScrollViewer>
</Grid>
The DataGrid itself has a built in scrollviewer so the outside one isn't needed. I think it is the DataGrid's scrollviewer that is causing your issue. Try getting rid of the outside ScrollViewer and add the attributes to the DataGrid, like this:
<DataGrid AutoGenerateColumns="False"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
...
>
...
</DataGrid>
If you need the outside scrollviewer for some reason, keep it but still disable the DataGrid's HorizontalScrollBarVisibility.
This is part hack, part real answer I think.
Hack part: In order to get the horizontal scroll bar to not show up, I simply disabled it in the DataGrid declaration. Then, to ensure that the column didn't get shaved off a little on the right side, I set row margin and padding in the style I used to turn off selection color.
Real part: Setting the vertical scrollbar to always show works properly as long as the height of the second row of the outtermost grid is set to "*" (asterisk). This ensures the DataGrid will use the proper amount of space when an expander is opened and there are too many rows to show.
The final DataGrid declaration looks like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Content="Import Data Mappings"
FontWeight="Bold"
HorizontalAlignment="Center"
Margin="4"
Padding="4"
Grid.Row="0" />
<DataGrid AutoGenerateColumns="False"
VerticalScrollBarVisibility="Visible"
HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Path=MyGroupedCollection, Mode=OneWay}"
HeadersVisibility="Column"
Grid.Row="1"
... >
<DataGrid.Resources>
<ResourceDictionary>
<Style x:Key="{x:Type DataGridCell}" TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="White" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="White" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="BorderBrush" Value="{x:Null}" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="{x:Type DataGridRow}" TargetType="{x:Type DataGridRow}">
<Setter Property="Margin" Value="0,4,0,4" />
<Setter Property="Background" Value="White" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="White" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="BorderBrush" Value="{x:Null}" />
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</DataGrid.Resources>
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<DataGridRowsPresenter />
</ItemsPanelTemplate>
</GroupStyle.Panel>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander Margin="4"
IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal"
Margin="4">
<TextBlock FontWeight="Bold"
FontSize="14"
Text="{Binding Path=Name}" />
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTemplateColumn Width="Auto">
<DataGridTemplateColumn.HeaderTemplate>
...
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock .../>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="*">
<DataGridTemplateColumn.HeaderTemplate>
...
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DockPanel LastChildFill="True">
<Button Style="{DynamicResource ResourceKey=MyButtonStyle}"
Content="Button Text"
Command="{Binding Path=MyButtonCommand}"
DockPanel.Dock="Left"/>
<ComboBox Margin="4"
Padding="4"
SelectedItem="{Binding Path=MySelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Path=MyAvailableFields}"
DockPanel.Dock="Left">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="{Binding Path=MyDisplayName}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DockPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>

WPF GridView export to CSV?

I have a ListView which is having GridView as its View.
See the sample code below:
<ListView ItemsSource="{Binding Path=Employees}" >
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Focusable" Value="False"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.Resources>
<Style TargetType="{x:Type CheckBox}" x:Key="DataGridCheckBox">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="IsEnabled" Value="True" />
<Setter Property="Margin" Value="4" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Width" Value="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type GridViewColumn}},Path=ActualWidth}" />
</Style>
</ListView.Resources>
<ListView.View>
<GridView x:Name="EmployeesGridView">
<GridViewColumn Header="IsEligible">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Style="{StaticResource DataGridCheckBox}" IsChecked="{Binding Path=IsSelected}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Name" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock>
<TextBlock>
<TextBlock Text="{Binding Path=Employee.Name}"/>
</TextBlock>
</TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Age">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Age}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
How can I export this data to CSV file. I am not getting any property by which I can get Rows present in GridView.
How can I do this. Please suggest.
You can create a SelectedPerson property in your ViewModel and bind ListView.SelectedItem to this property.

How to select ListView row if control in data template is clicked

I have a ListView that is using a DataTemplate. I swap out the Item DataTemplate based on the IsSelected property of the particular item. This allows me to display an edit template and a read template. The ListView contains two columns. In read mode the two columns are readonly TextBoxes and in edit mode the left column is a editable TextBox and the right column is a drop down. Everything works great as long as I don't click directly on one of the TextBoxes when in read mode. If I click outside the control the row is selected just fine, when selecting inside the control, however, the row is not selected. This prevents me from entering edit mode when one of the cells are clicked.
I've pasted my xaml below. You can see that the GridBlock and GridEdit styles will be controlled by the IsSelected property of the ListView. This is what allows me to swap out the DataTemplate (really hide or collapse) based on that DP. I've further specialized these styles to allow for watermarked textboxes when the value is empty and the control doesn't have focus. I think this is where my problem lies but for the life of me I can't think of a way to do this declaratively. Also, I'm new to WPF so I'm sure there is a pattern for this sort of thing it's just very difficult to formulate a query that will return meaningful results from google or bing. Thanks for any and all help in advance.
Here are my styles and datatemplates:
<Style TargetType="{x:Type FrameworkElement}" x:Key="GridBlockStyle">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Visibility"
Value="{Binding Path=IsSelected,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ListViewItem}},
Converter={StaticResource boolToVis},
ConverterParameter=False}" />
</Style>
<Style TargetType="{x:Type FrameworkElement}" x:Key="GridEditStyle">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Visibility"
Value="{Binding Path=IsSelected,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ListViewItem}},
Converter={StaticResource boolToVis},
ConverterParameter=True}" />
</Style>
<Style x:Key="TextBoxReadOnly" TargetType="{x:Type TextBox}" BasedOn="{StaticResource GridBlockStyle}">
<Setter Property="KeyboardNavigation.TabNavigation" Value="None" />
<Setter Property="AllowDrop" Value="true" />
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="Padding" Value="8,5,3,3" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Label x:Name="TextPrompt" Content="{TemplateBinding Tag}" Visibility="Collapsed" Focusable="False" Foreground="Silver"></Label>
<ScrollViewer Margin="0" x:Name="PART_ContentHost" Foreground="{DynamicResource OutsideFontColor}" />
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused" Value="False"></Condition>
<Condition Property="Text" Value=""></Condition>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Visibility" TargetName="TextPrompt" Value="Visible"></Setter>
</MultiTrigger.Setters>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="DimGray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TextBoxEditable" TargetType="{x:Type TextBox}" BasedOn="{StaticResource GridEditStyle}">
<Setter Property="KeyboardNavigation.TabNavigation" Value="None" />
<Setter Property="AllowDrop" Value="true" />
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="Padding" Value="8,5,3,3" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Border x:Name="BorderBase" Background="White" BorderThickness="1.4,1.4,1,1"
BorderBrush="Silver" />
<Label x:Name="TextPrompt" Content="{TemplateBinding Tag}" Visibility="Collapsed" Focusable="False" Foreground="Silver"></Label>
<ScrollViewer Margin="0" x:Name="PART_ContentHost" Foreground="{DynamicResource OutsideFontColor}" />
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused" Value="False"></Condition>
<Condition Property="Text" Value=""></Condition>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Visibility" TargetName="TextPrompt" Value="Visible"></Setter>
</MultiTrigger.Setters>
</MultiTrigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderThickness" TargetName="BorderBase" Value="2.4,2.4,1,1"></Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="DimGray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And here is my ListView view:
<ListView.View>
<GridView>
<GridViewColumn Width="120">
<GridViewColumnHeader Content="Resource ID" />
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBox Margin="3" Tag="Enter Resource ID" Text="{Binding Path=ResourceID, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource TextBoxReadOnly}" IsReadOnly="True" />
<TextBox Width="90" Tag="Enter Resource ID" Margin="3"
Style="{StaticResource TextBoxEditable}" Text="{Binding Path=ResourceID, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="120">
<GridViewColumnHeader Content="Code" />
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBox Margin="3" Tag="Enter Code" Text="{Binding Path=Code}"
Style="{StaticResource TextBoxReadOnly}" IsReadOnly="True" />
<ComboBox Margin="3" Style="{StaticResource GridEditStyle}"
ItemsSource="{Binding Source={StaticResource CodeViewSource}, Mode=OneWay}"
SelectedItem="{Binding Path=Code, Mode=TwoWay}"
IsSynchronizedWithCurrentItem="False"
util:ComboBoxWidthFromItemsBehavior.ComboBoxWidthFromItems="True" />
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="120">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Margin="5" Content="Delete"
Command="{Binding Path=DataContext.RemoveORIEntryCommand,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type UserControl}}}">
<Button.Resources>
<Converter:AgencyItemIDParametersConverter x:Key="RemoveListViewItemParametersConverter" />
</Button.Resources>
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource RemoveListViewItemParametersConverter}">
<MultiBinding.Bindings>
<Binding Path="AgencyID" />
<Binding Path="ID" />
</MultiBinding.Bindings>
</MultiBinding>
</Button.CommandParameter>
</Button>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
I had a similar problem in a ListView.
Basically each item of the ListView had a RadioButton and a TextBox. The RadioButton IsChecked property was binded to the ListViewItem select property. The thing was that when I selected the TextBox the item was not selected, hence not checking the RadioButton.
I managed to solve the problem with the IsKeyboardFocusWithin property. I set a trigger in the ListViewItem style so when this property is true the isSelected property would be set to true also.
You can check this thread.

Categories

Resources