【问题标题】:WPF ComboBox binding ItemsSourceWPF ComboBox 绑定 ItemsSource
【发布时间】:2015-04-07 01:26:27
【问题描述】:

我是 WPF 的初学者,正在尝试将 ComboBox 的项目绑定到 ObservableCollection

我使用了这个代码:

XAML

<Window x:Class="comboBinding2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ComboBox x:Name="cmbTest" ItemsSource="{Binding Path=cmbContent}" Width="200" VerticalAlignment="Center" HorizontalAlignment="Center" />
    </Grid>
</Window>

C#

public MainWindow()
{
    cmbTest.ItemsSource = cmbContent;
    cmbContent.Add("test 1");
    cmbContent.Add("test 2");

    InitializeComponent();
}

public ObservableCollection<string> cmbContent { get; set; }

在我尝试调试之前,我在此代码上没有收到任何错误,它会引发错误:

TargetInvocationError

PresentationFramework.dll 中出现“System.Reflection.TargetInvocationException”类型的未处理异常

谁能告诉我我做错了什么?

【问题讨论】:

    标签: c# wpf xaml binding combobox


    【解决方案1】:

    您当前的实施存在一些问题。正如其他人所说,您的列表当前为NULL,并且未设置Window的DataContext

    不过,我建议(尤其是因为您刚刚开始使用 WPF)正在学习使用MVVM 以更“正确”的方式进行绑定。

    参见下面的简化示例:

    首先,您要设置WindowDataContext。这将允许XAML“查看”您的ViewModel 中的属性。

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new ViewModel();
        }
    }
    

    接下来,只需设置一个 ViewModel 类,该类将包含所有 Window's 绑定元素,例如:

    public class ViewModel
    {
        public ObservableCollection<string> CmbContent { get; private set; }
    
        public ViewModel()
        {
            CmbContent = new ObservableCollection<string>
            {
                "test 1", 
                "test 2"
            };
        }
    }
    

    最后,更新您的 XAML 以使绑定路径与集合匹配:

    <Grid>
        <ComboBox Width="200"
              VerticalAlignment="Center"
              HorizontalAlignment="Center"
              x:Name="cmbTest"
              ItemsSource="{Binding CmbContent}" />
    </Grid>
    

    【讨论】:

    • 这很好用,但是如何从 MainWindow 向 CmbContent 添加其他字符串???
    • 您想实时添加字符串,还是让组合框包含其他字符串?
    • 我要实时添加字符串
    • 好的,实时基于用户界面控件(即文本框+按钮)?还是幕后?你在寻找什么机制
    • 我找到了一种方法来做到这一点 ViewModel vm = new ViewModel();数据上下文 = vm; vm.cmbContent.Add("test 3"); 感谢您的帮助。
    【解决方案2】:
       public MainWindow()
        {
    
            InitializeComponent();
            cmbContent=new ObservableCollection<string>();
            cmbContent.Add("test 1");
            cmbContent.Add("test 2");
            cmbTest.ItemsSource = cmbContent;
    
        }
        public ObservableCollection<string> cmbContent { get; set; }
    

    上面的代码没有使用任何绑定,也就是说使用它不需要绑定Combobox'sItemSource,如果你不想使用绑定你需要

    首先:使用以下方法从 CodeBehind (ViewModel) 设置 DataContext:

    this.DataContext=this;
    

    或来自 Xaml:

    DataContext="{Binding RelativeSource={RelativeSource Self}}">
    

    第二:使用ItemSource中的Binding就像你做ItemsSource="{Binding Path=cmbContent}"你也可以考虑使用INotifyPropertyChanged接口如果你想通知UI以防属性发生任何变化

    【讨论】:

      【解决方案3】:

      cmbContent 为空,因为您从未将其设置为任何值。我猜这个错误实际上是一个NullReferenceException,但它显示为TargetInvocationException,因为它在视图的构造函数中。

      另外,您将ComboBoxItemsSource 设置了两次(一次在绑定中,一次在构造函数中)。你不需要这样做。选一个。您的绑定将无法按其编写方式工作(因为未设置 DataContext),因此您应该在代码中执行此操作,或设置 DataContext(如 Nadia 建议的那样)。

      【讨论】:

        猜你喜欢
        • 2015-11-16
        • 1970-01-01
        • 2020-01-30
        • 1970-01-01
        • 2011-02-27
        • 1970-01-01
        • 1970-01-01
        • 2013-06-30
        • 1970-01-01
        相关资源
        最近更新 更多