0
votes

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:

  1. I've defined style for the ListView which I add border, scrollviewer and ItemsPresenter (which represent the collection of ListViewItem).

  2. Then I've defined style for ListViewItem which consist of a Button, command, style trigger.

  3. Lastly, in the UserControl/MainWindow, I add the ListView.

  4. 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>
1
Not sure if it's a good idea, but you could just set ((ListBox)sender).SelectedItem = null; in a SelectedChanged event handler. The VM property would be set to the selected item, and immediately back to null.Clemens
The other option is for the viewmodel to nullify SelectionModel in an action passed to Displatcher.BeginInvoke() with a priority of ApplicationIdle. The trouble you're having is that you can't set the selected item back to null until the ListView has finished setting it to value. 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
Hi Clemens & Ed Plunkett. I update the question wrt to your suggestion. I would not able to proceed looking at my current competency.Irwan Hamid
Hi fruggiero. The other question is for disabling the SelectionItem. However in my case, I would want to find the way of not retaining the SelectionItem as I would need to know the value of SelectionItem first to do some logic. But your link does provide me with a good reading. Thanks.Irwan Hamid

1 Answers

0
votes

Setting Focusable property to false in ListBoxItem style may help you:

<Style x:Key="{x:Type ListBoxItem}" TargetType="{x:Type ListBoxItem}">
  <Setter Property="Focusable" Value="False" />
</Style>