简体   繁体   中英

WPF ListView Change Selected Item on ComboBox cell item focus or change

For a ListView I have, there are several comboboxes in the row. I also have a textbox binded to the selected row to show other information from the row below the ListView. The problem is that when you click on a ComboBox in a row, the ListView selected item/index doesn't change for that row. How can I change the selected item in the ListView for a row when a ComboBox within that row is selected?

Here is my ListView with ComboBox:

<ListView Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4" VerticalAlignment="Stretch" 
        ItemsSource="{Binding Equations.DataExpressions}" SelectedItem="{Binding Equations.SelectedExpression}" SelectedIndex="0">
<ListView.Resources>
    <Style TargetType="{x:Type ListViewItem}">
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        <Setter Property="VerticalContentAlignment" Value="Stretch" />
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsValidExpression}" Value="false">
                <Setter Property="Background" Value="#FF8080" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</ListView.Resources>
<ListView.View>
    <GridView>
        <GridViewColumn Header="Path" Width="90">
            <GridViewColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.PathItems}" 
                                SelectedValue="{Binding EvaluatedPath}" Margin="-6, 0, -6, 0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                    </ComboBox>
                </DataTemplate>
            </GridViewColumn.CellTemplate>
        </GridViewColumn>
    </GridView>
</ListView.View>

Add an event handler to your Style and handle the PreviewMouseLeftButtonDown event:

private void lv_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    ListViewItem lvi = (ListViewItem)sender;
    ListView lv = FindParent<ListView>(lvi);
    lv.SelectedItem = lvi.DataContext;
}

private static T FindParent<T>(DependencyObject dependencyObject) where T : DependencyObject
{
    var parent = VisualTreeHelper.GetParent(dependencyObject);

    if (parent == null) return null;

    var parentT = parent as T;
    return parentT ?? FindParent<T>(parent);
}

XAML:

<Style TargetType="{x:Type ListViewItem}">
    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    <Setter Property="VerticalContentAlignment" Value="Stretch" />
    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="lv_PreviewMouseLeftButtonDown" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsValidExpression}" Value="false">
            <Setter Property="Background" Value="#FF8080" />
        </DataTrigger>
    </Style.Triggers>
</Style>

Note that since this is purely view/control related logic it should be implemented in the view (code-behind). A view model is not responsible for how a control behaves so this doesn't break the MVVM pattern.

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