Could we set a ListView to not retain a selection after a user click on a ListViewItem? Could it possibly been done?
Note: it is not about changing the style on 'IsSelected' but actually to not having the selection after the user click it.
I have try the following but it was not successful. In the View:
<ListView Grid.Row="1"
ItemsSource="{Binding Models}"
SelectedItem="{Binding SelectedModel}"
DisplayMemberPath="DisplayContent"/>
In the ViewModel whom having the View DataContext:
public LookupItemWrapper SelectedModel
{
get { return _selectionModel; }
set
{
_selectionModel = value;
OnPropertyChanged();
if (value != null)
{
_eventAggregator.GetEvent<OnRequisitionSelectionInRequisitionProjectNavigationEvent>().Publish(
new OnRequisitionSelectionInRequisitionProjectNavigationEventArgs
{
Requisitionid = _selectionModel.Id
});
}
_selectionModel = null;
OnPropertyChanged();
}
}
I guess I know a way to imitate that by having ItemsControl with Button as its item. However I really like to know if I could do this with a ListView.
Update
I have written the following event handler wrt Clemens & Ed Plunkett suggestion. But where do I place the code? I should not place it inside the VM constructor as everytime SelectedModel is set to null, so does with this event handler logic.
SelectedModel.PropertyChanged += (s, e) =>
{
if (SelectedModel != null)
{
((ListView)s).SelectedItem = null;
}
};
Update With Answer
I have try using ItemsControl. I write the ItemsControl's ItemTemplate which has a Button that bind with a command for mouse click.This work fine. I also write the ItemsControl's ItemTemplate which I intend to define the its style, however ItemContainerStyle can only has TargetType of ContentPresenter. Meaning I can't add Border, ScrollViewer, Grid or any other UI element inside the style. Sure, I can write it directly on the UserControl/MainWindow such as following:
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<Border BorderBrush="Black" BorderThickness="10">
<ItemsControl Grid.Column="0"
ItemsSource="{Binding Friends}"
ItemContainerStyle="{StaticResource ItemContainerStyle}"
ItemTemplate="{StaticResource ItemTemplate}"/>
</Border>
</ScrollViewer>
I found out ItemsControl is raw and not elegent.
So I come back to ListView. What I have done is:
I've defined style for the ListView which I add border, scrollviewer and ItemsPresenter (which represent the collection of ListViewItem).
Then I've defined style for ListViewItem which consist of a Button, command, style trigger.
Lastly, in the UserControl/MainWindow, I add the ListView.
I have set the ListView Style property to the defined ListView style and set its ItemContainerStyle property to the defined style of ListViewItem.
I do not set or use ListView SelectedItem property.
I response to user click not by monitoring to the property bind to the SelectedItem rather by handling the button command binding.
This is easier and much elegent.
<ListView Grid.Row="1"
ItemsSource="{Binding Models}"
ItemContainerStyle="{StaticResource RequisitionNavigationItemListViewItemStyle}"
Style="{StaticResource RequisitionNavigationListViewStyle}"/>
Here is both styles definition:
<Style x:Key="RequisitionNavigationItemListViewItemStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="Background" Value="{StaticResource ViewListBackgroundBrush}"/>
<Setter Property="Foreground" Value="{StaticResource ViewListForegroundBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Button Content="{Binding DisplayContent}"
Command="{Binding DataContext.OnSelectingRequisitionCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
CommandParameter="{Binding}">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid x:Name="grid">
<Border x:Name="BorderInButton" Background="{StaticResource RequisitionNavigationBackgroundBrush}" Height="65" SnapsToDevicePixels="True">
<ContentPresenter x:Name="ContentPresenterInButton" TextBlock.Foreground="{StaticResource RequisitionNavigationForegroundBrush}">
<ContentPresenter.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="Margin" Value="10"/>
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="BorderInButton" Property="Background" Value="{StaticResource RequisitionNavigationBackgroundHighlightedBrush}"/>
<Setter TargetName="ContentPresenterInButton" Property="TextBlock.Foreground" Value="{StaticResource RequisitionNavigationForegroundHighlightedBrush}"/>
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="RequisitionNavigationListViewStyle" TargetType="{x:Type ListView}">
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListView}">
<Border x:Name="Bd" BorderBrush="{StaticResource ViewListBorderBrush}" BorderThickness="2 1 4 4" Background="{StaticResource ViewListBackgroundBrush}" Padding="0" SnapsToDevicePixels="True">
<ScrollViewer Style="{StaticResource ScrollViewerStyle}">
<ItemsPresenter/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
((ListBox)sender).SelectedItem = null;
in aSelectedChanged
event handler. The VM property would be set to the selected item, and immediately back to null. – Clemensvalue
. But I'd much rather add an event handler to the view than besmirch the viewmodel's innocence that way. – 15ee8f99-57ff-4f92-890c-b56153