简体   繁体   中英

WPF trigger for selected items

I am using the MVVM light framework. On one of my pages I have a listbox which has a bound list and a bound selected item. I have a style that should highlight the selected item in that listbox. However, the item is not highlighted until I physically click it (It will not highlight the item when it is just bound).

XAML:

<UserControl.Resources>
        <hartvm:ViewLocator x:Key="HartvilleLocator" d:IsDataSource="True" />
        <DataTemplate DataType="{x:Type Quotes:QuotePetSummaryItem}">
            <Views:QuoteSummaryItem DataContext="{Binding}" />
        </DataTemplate>
        <Style x:Key="ListboxItemStyle" TargetType="{x:Type ListBoxItem}">
            <Style.Resources>
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red"/>
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black"/>
            </Style.Resources>
            <Setter Property="BorderBrush" Value="Red"/>
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="False">
                    <Setter Property="BorderThickness" Value="0"/>
                    <Setter Property="Opacity" Value="40"/>
                </Trigger>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="BorderThickness" Value="1"/>
                    <Setter Property="Opacity" Value="100"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </UserControl.Resources>
    <UserControl.DataContext>
        <Binding Source="{StaticResource HartvilleLocator}" Path="QuoteSummary" />
    </UserControl.DataContext>
    <Border>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Border BorderBrush="Black" BorderThickness="0">
                <TextBlock TextWrapping="Wrap" Text="Quote Summary" Margin="5,0,0,0" FontSize="21.333" Foreground="{DynamicResource ControlHeaderBrush}" FontFamily="Verdana"/>
            </Border>
            <ScrollViewer d:LayoutOverrides="Height" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" Grid.Row="1" Margin="10,10,5,10">
                <telerik:RadBusyIndicator IsBusy="{Binding IsProcessing}">
<ListBox ItemsSource="{Binding DefaultList}" SelectedItem="{Binding SelectedDefault}" Background="{x:Null}" ItemContainerStyle="{StaticResource ListboxItemStyle}"> 

                    <ListBox.ItemsPanel>
                        <ItemsPanelTemplate>
                                <WrapPanel Orientation="Horizontal" />
                            </ItemsPanelTemplate>
                    </ListBox.ItemsPanel>
                    </ListBox>
                </telerik:RadBusyIndicator>
            </ScrollViewer>
        </Grid>
    </Border>
</UserControl>

Code (To programmatically select the item in the list box):

public QuotePetSummaryItem SelectedDefault { get; set; }

private void SelectDefault()
        {
            if (DefaultList== null || DefaultList.First().Pet == null) return;

            SelectedDefault = DefaultList.First();

            MessengerService.Send(SelectionMessage.Create(SelectedDefault.SubDefault));
        }

The message being sent is not important and does some other work on another page. The SelectedDefault property is the only thing that is used for this example.

Someone have an idea as to what I need to do to get this working?

It looks like the binding (and thus your view) doesn't know that the selected item property has changed.

In the setter of SelectedDefault you need to create a notification of some sort using the INotifyPropertyChanged interface.

I just took a quick look at the MVVM light framework and judging by the samples, if your viewmodel inherits from ViewModelBase use a field-backed property and call RaisePropertyChanged:



    private QuotePetSummaryItem _selectedDefault;
    public QuotePetSummaryItem SelectedDefault
    {
        get { return _selectedDefault; }
        set
        {
            _selectedDefault = value;
            RaisePropertyChanged("SelectedDefault");
        }
    }

1st you have to set the binding mode for selecteditem to twoway

<ListBox ItemsSource="{Binding DefaultList}" SelectedItem="{Binding SelectedDefault, Mode=TwoWay}" Background="{x:Null}" ItemContainerStyle="{StaticResource ListboxItemStyle}"> 

2nd in your viewmodel you have to implement INotifyPropertyChanged and raise it properly. look at Rock Counters answer.

if all this not work check your vs output window for binding errors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM