WPF绑定问题

3

我开始学习WPF和绑定,但有一些奇怪的行为我不理解。

示例1: 一个非常简单的WPF表单,只有一个组合框(名称为C),在构造函数中包含以下代码:

    public Window1()
    {
        InitializeComponent();

        BindingClass ToBind = new BindingClass();
        ToBind.MyCollection = new List<string>() { "1", "2", "3" };

        this.DataContext = ToBind;

        //c is the name of a combobox with the following code :  
        //<ComboBox Name="c" SelectedIndex="0" ItemsSource="{Binding Path=MyCollection}" />
        MessageBox.Show(this.c.SelectedItem.ToString());
    }

您能解释一下为什么由于c.SelectedItem为空值,这段代码会崩溃吗?

所以我想...没问题,因为它在构造函数中,让我们将代码放在Loaded表单事件中:

        public Window1()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        BindingClass ToBind = new BindingClass();
        ToBind.MyCollection = new List<string>() { "1", "2", "3" };
        this.DataContext = ToBind;
        MessageBox.Show(this.c.SelectedItem.ToString());
    }

同样的问题,this.c.SelectedItem 为空...

备注:如果我移除 Messagebox 部分,那么绑定就正常工作了,我可以在组合框中看到值。就像需要一些时间来设置数据上下文一样。但是如何知道何时完成绑定?

感谢您的帮助。

3个回答

2

由于selectionchanged尚未触发,因此selecteditem仍为空。

private void c_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
   MessageBox.Show(this.c.SelectedItem.ToString());
}

如果您是WPF的新手,我建议您去了解MVVM模式。这里有一个非常好的介绍视频:http://blog.lab49.com/archives/2650


实际上,问题不仅在于所选项为空值。下拉框的反应就好像根本没有绑定(项目也为空值)。很奇怪,因为在Silverlight 3中是正常的。 - Fabian
是的,我没去检查那个:P。有点奇怪,在Silverlight中可以工作但在WPF中却不行。也许它们有一种不同的加载控件的方式。我检查了OnContentRendered和MyCollection已经在渲染控件本身之前设置好了。我现在没有时间再深入研究了,但Red Gates .net Reflector是一个很好的工具,可以查看.net框架中发生了什么。它帮助我找到了很多关于WPF的奇怪问题。对于我的错误答案感到抱歉,但我希望你能看看MVVM,因为它是开发WPF应用程序的一种非常好的模式。 - Michael
谢谢你,Michael。我正在将一个项目从Silverlight 3迁移到WPF,乍一看似乎很容易,但它们之间确实存在非常讨厌的奇怪差异,使得事情变得相当复杂! :) - Fabian
只是另一个小问题,通常你在哪里绑定视图模型到你的视图(WPF表单)?你将视图模型的接口传递给WPF表单构造函数吗? - Fabian
好的,我知道了。因为我可能很快就要将一些WPF应用程序转移到Silverlight上。在哪里绑定视图模型有点取决于情况。有时候我会在构造函数中传递它,特别是当我使用IOC时。但有时我会先创建视图模型,然后创建窗口,并将视图模型设置为窗口的数据上下文。我想这取决于你的个人喜好。 - Michael

0

感谢您的评论,应该是这样的,我尝试了一下,它可以正常工作:

    BindingClass ToBind = new BindingClass();
    public Window1()
    {
        InitializeComponent();
        ToBind.MyCollection = new List<string>() { "1", "2", "3" };

        this.DataContext = ToBind;
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        MessageBox.Show(this.c.SelectedItem.ToString());
    }

所以在这里,即使没有在屏幕上绘制,已经获取到了选中的项目...非常奇怪。

0

你的绑定发生在 Window_Loaded 事件期间,但它还没有被绘制到屏幕上,因此还没有 SelectedItem。

你需要监听你的 Binding 或 DataContext 的 PropertyChanged 事件。然后在 OnPropertyChanged 时弹出你的消息框。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接