简体   繁体   English

绑定到 ObservableCollection (WPF) 时无法更改 ComboBox 选择

[英]Can't change ComboBox selection when bound to ObservableCollection (WPF)

I'm trying to create an edit form for editing properties of a custom set of TV Series objects.我正在尝试创建一个编辑表单来编辑一组自定义电视剧对象的属性。 One of the properties holds a collection of all owned media formats (DVD, Blu-ray, etc) for that particular series that will be displayed in a ComboBox .其中一个属性包含将在ComboBox显示的特定系列的所有拥有的媒体格式(DVD、蓝光等)的集合。 Items are added to the ComboBox via a separate popup window and items are to be removed from the ComboBox by selecting the item and clicking a remove Button .项目被添加到ComboBox通过一个单独的弹出窗口和物品都予以除名ComboBox通过选择该项目,并单击删除Button

I can add new entries to the MediaOwned ComboBox just fine, but when I try to select a specific ComboBox item to test the remove Button I find that I can only ever select the first entry.我可以向 MediaOwned ComboBox添加新条目就好了,但是当我尝试选择特定的ComboBox项目来测试删除Button我发现我只能选择第一个条目。 Can someone please tell me if I've missed something embarrassingly obvious, thanks.有人可以告诉我我是否遗漏了一些令人尴尬的明显内容,谢谢。

Here is the problematic property:这是有问题的财产:

    private ObservableCollection<string> _mediaOwned = new ObservableCollection<string>();
    public ObservableCollection<string> MediaOwned
    {
        get { return _mediaOwned; }
        set
        {
            _mediaOwned = value;
            OnPropertyChanged(new PropertyChangedEventArgs("MediaOwned"));
        }
    }

Here are the other relevant code behind:以下是其他相关代码:

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        // Create binding for the ListBox.
        Binding listBinding = new Binding();
        listBinding.Source = show.Series;
        listBinding.Mode = BindingMode.OneWay;
        listBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
        lbSeries.SetBinding(ListBox.ItemsSourceProperty, listBinding);

        // Create binding for the ComboBox.
        Binding myBinding = new Binding();
        myBinding.Path = new PropertyPath("MediaOwned");
        myBinding.Mode = BindingMode.TwoWay;
        myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
        cbMediaOwned.SetBinding(ComboBox.ItemsSourceProperty, myBinding);
    }

    private void btnRemoveMedia_Click(object sender, RoutedEventArgs e)
    {
        Series series = (Series)lbSeries.SelectedItem;
        series.MediaOwned.Remove(cbMediaOwned.Text);
    }

And here is the XAML code:这是 XAML 代码:

        <Border Style="{StaticResource PanelBorderStyle}" DockPanel.Dock="Left" Margin="0,8,8,0" 
                DataContext="{Binding ElementName=lbLists, Path=SelectedItem}">
            <DockPanel VerticalAlignment="Top">
                <StackPanel>
                    <ListBox x:Name="lbSeries" Style="{StaticResource BasicListStyle}" Width="180" Height="300" 
                             DisplayMemberPath="Title" SelectionMode="Single" LayoutUpdated="lbSeries_LayoutUpdated">
                    </ListBox>
                </StackPanel>
                
                <StackPanel x:Name="editPanel" DataContext="{Binding ElementName=lbSeries, Path=SelectedItem}">
                    <StackPanel  Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0, 4, 0, 0">
                        <TextBlock Style="{StaticResource SmallFont}" Width="100">Title</TextBlock>
                        <TextBox x:Name="txtTitle" Style="{StaticResource TextBoxStyle}" Text="{Binding Path=Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="200" Margin="8, 8, 16, 8"></TextBox>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top">
                        <TextBlock Style="{StaticResource SmallFont}" Width="100">Media owned</TextBlock>

                        <ComboBox x:Name="cbMediaOwned" Style="{StaticResource ComboBoxStyle}"  Width="150" Margin="8,8,6,8" 
                                ></ComboBox>

                        <Button x:Name="btnAddMedia" Style="{StaticResource ToolbarButtonStyle}" Click="btnAddMedia_Click" Margin="0">
                            <StackPanel ToolTip="Add media">
                                <Image Source="Images/add.png" />
                            </StackPanel>
                        </Button>
                        <Button x:Name="btnRemoveMedia" Style="{StaticResource ToolbarButtonStyle}" Click="btnRemoveMedia_Click" Margin="4">
                            <StackPanel ToolTip="Remove media">
                                <Image Source="Images/remove.png" />
                            </StackPanel>
                        </Button>
                    </StackPanel>
                </StackPanel>
            </DockPanel>
        </Border>

Alternatively I can also remove the binding code in the code behind and replace the ComboBox with the below code (but I still get the same problem - I can't select anything in the ComboBox ):或者,我也可以删除后面代码中的绑定代码,并用下面的代码替换ComboBox (但我仍然遇到同样的问题 - 我无法在ComboBox选择任何内容):

                    <ComboBox x:Name="cbMediaOwned" Style="{StaticResource ComboBoxStyle}"  Width="150" Margin="8,8,6,8" ItemsSource="{Binding ElementName=lbSeries, Path=SelectedItem.MediaOwned, UpdateSourceTrigger=PropertyChanged}" 
                              SelectedItem="{Binding SelectedMedia, UpdateSourceTrigger=PropertyChanged}"></ComboBox>

SelectedMedia property: SelectedMedia 属性:

    private string _selectedMedia = "";
    public string SelectedMedia
    {
        get { return _selectedMedia; }
        set
        {
            _selectedMedia = value;
            OnPropertyChanged(new PropertyChangedEventArgs("SelectedMedia"));
        }
    }

Here is my xaml:这是我的xaml:

<ComboBox x:Name="Models_ComboBox"
      Width="110"
      Text="Model"
      ItemsSource="{Binding Models}"
      SelectedItem="{Binding SelectedModel}"
      DisplayMemberPath="Model"
      MouseDoubleClick="Models_ComboBox_MouseDoubleClick"
      SelectionChanged="Models_ComboBox_SelectionChanged"/>

Here are my VM properties:这是我的 VM 属性:

private DataTable models;
public DataTable Models
{
    get { return models; }
    set
    {
        if (models != value)
        {
            models = value;
            OnPropertyChanged(nameof(Models));
        }
    }
}

and

private DataRowView selectedModel;
public DataRowView SelectedModel
{
    get { return selectedModel; }
    set
    {
        if (selectedModel != value)
        {
            selectedModel = value;
            if (value != null)
            {
                InitializeOptions(value["Model"].ToString());
            }
            OnPropertyChanged(nameof(SelectedModel));
        }
    }
}

As you can see, the ItemsSource and the SelectedItem of the ComboBox are bound to two different properties in the ViewModel.如您所见,ComboBox 的 ItemsSource 和 SelectedItem 绑定到 ViewModel 中的两个不同属性。 The ItemsSource is bound to a DataTable populated from a Database. ItemsSource 绑定到从数据库填充的 DataTable。 Once the user selects a Model, then there are other option ComboBoxes that are populated based on that selection.一旦用户选择了一个模型,就会有其他选项组合框根据该选择进行填充。

Fixed the problem myself.自己解决了这个问题。 I had a line of code that was automatically setting the SelectedIndex of the ComboBox without me realizing.我有一行代码在我没有意识到的情况下自动设置了ComboBoxSelectedIndex

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

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