简体   繁体   English

当ComboBox中的选择更改时,以ComboBox作为项目模板的ListView不会更新源

[英]ListView with ComboBox as item template don't update source when selection in ComboBox changes

I have ListView bound to ObservableCollection<string> and each item should be displayed as ComboBox . 我将ListView绑定到ObservableCollection<string>并且每个项目都应显示为ComboBox Problem is, when i change selection in ComboBox , it doesn't update ObservableCollection<string> . 问题是,当我更改ComboBox选择时,它不会更新ObservableCollection<string> Here is xaml: 这是xaml:

<ListView ItemsSource="{Binding CellValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                <ListView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ListView.ItemsPanel>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding Path=DataContext.Column.CellValueChoices, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" SelectedIndex="0" IsEditable="True">
                            <i:Interaction.Behaviors>
                                <behaviors:CellFocusBehavior/>
                                <behaviors:FocusOnLoadBehavior/>
                            </i:Interaction.Behaviors>
                            <ComboBox.InputBindings>
                                <KeyBinding Command="{Binding Path=DataContext.ValidateAndInsertNewCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" Key="Tab"/>
                            </ComboBox.InputBindings>
                        </ComboBox>
                    </DataTemplate>
                </ListView.ItemTemplate>
</ListView>

DataContext for ListView is CellViewModel object that contains ObservableCollection<string> CellValue . ListView DataContextCellViewModel对象,包含ObservableCollection<string> CellValue

Looking at your xaml, it seems to me that you think "ItemsSource="{Binding CellValue, Mode=TwoWay" is the way of binding a wpf control to it's corresponding VM property which is not quite right. The Itemsource binding should only be one way as the ViewModel loading the list that implement INotifyCollectionChanged to the GUI in one-way fashion. Making the ItemsSource binding to TwoWay doesn't make the GUI know how to update all the control's value inside the DataTemplate back to your ViewModel. 看着您的xaml,在我看来,您认为“ ItemsSource =” {Binding CellValue,Mode = TwoWay“是将wpf控件绑定到其对应的VM属性的方式,这不太正确。Itemsource绑定只能是一个就像ViewModel以单向方式将实现INotifyCollectionChanged的列表加载到GUI一样,将ItemsSource绑定到TwoWay并不能使GUI知道如何将DataTemplate内部的所有控件值更新回ViewModel。

Instead, you should binding each control to each one of your ViewModel property in order to do that. 相反,您应该将每个控件绑定到ViewModel属性的每个控件上,以实现此目的。 I made you a sample for it. 我给你做了一个样品。

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class OrderViewModel : ViewModelBase
{
    public ObservableCollection<string> ComboBoxOptions { get; set; }

    private string orderId;
    private string instrumentId;
    private string selectedComboOption;

    public OrderViewModel()
    {
        ComboBoxOptions = new ObservableCollection<string>
        {
            "Option1",
            "Option2",
            "Option3",
        };            
    }

    public string OrderId
    {
        get { return orderId; }
        set
        {
            orderId = value;
            OnPropertyChanged();
        }
    }

    public string InstrumentId
    {
        get { return instrumentId; }
        set
        {
            instrumentId = value;
            OnPropertyChanged();
        }
    }

    public string SelectedComboOption
    {
        get { return selectedComboOption; }
        set
        {
            selectedComboOption = value;
            OnPropertyChanged();
        }
    }
}

[Export]
public class MainViewModel : ViewModelBase
{
    private OrderViewModel selectedOrder;
    public ObservableCollection<OrderViewModel> Orders { get; set; }        

    public MainViewModel()
    {
        Orders = new ObservableCollection<OrderViewModel>
        {
            new OrderViewModel {OrderId = "Order1", InstrumentId = "Instrument1"},
            new OrderViewModel {OrderId = "Order2", InstrumentId = "Instrument2"},
            new OrderViewModel {OrderId = "Order2", InstrumentId = "Instrument3"}
        };
    }

    public OrderViewModel SelectedOrder
    {
        get { return selectedOrder; }
        set
        {
            selectedOrder = value;
            OnPropertyChanged();
        }
    }
}

<Window x:Class="WpfTestProj.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:local="clr-namespace:WpfTestProj"
    mc:Ignorable="d" 
    d:DataContext="{d:DesignInstance Type=local:MainViewModel, IsDesignTimeCreatable=False}"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <ListView ItemsSource="{Binding Orders}" SelectedItem="{Binding SelectedOrder}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBox Text="{Binding OrderId}" />
                    <TextBox Text="{Binding InstrumentId}" />
                    <ComboBox ItemsSource="{Binding ComboBoxOptions}"                                  
                              SelectedItem="{Binding SelectedComboOption}"/>
                </StackPanel>                    
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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