ListBox.ItemsSource {Binding ...}不起作用,但如果我在代码中设置ItemsSource,它就是花花公子!

时间:2010-10-29 14:15:46

标签: c# wpf data-binding xaml itemssource

我正在尝试使用WPF,但我遇到了一个我似乎无法弄清楚的问题,尽管我之前已经完成了Silverlight的一些工作并且成功地使用了DataContexts,Data Bindings和INPC。这次我被卡住了......

我正在使用此代码创建应用程序主窗口的实例:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);
    MainWindow window = new MainWindow();
    var viewModel = new MainVM(); //implements INotifyPropertyChanged
    viewModel.Load("Brighton+UK");
    window.DataContext = viewModel;
    window.weatherList.ItemsSource = viewModel.WeatherInfo; //THIS WORKS
    window.Show();
}

当我像这样运行应用程序时,一切都很好,主窗口上的ListBox显示了MainVM的WeatherInfo ObservableCollection中找到的项目。

然而,当我对该行进行注释然后进入我的主窗口的XAML时,并在XAML中设置weatherList ListBox的ItemsSource属性,如下所示:

<ListBox x:Name="weatherList" 
    Grid.Row="0" 
    ItemContainerStyle="{StaticResource stretched}" 
    ItemsSource="{Binding WeatherInfo}" />

虽然我将MainWindow的DataContext设置为MainVM的一个实例(如C#代码摘录中所示),但列表并没有按照我的预期填充。

有人可以向我解释,为什么?

== EDIT ==

我的所有主窗口的XAML:

<Window x:Class="DataTemplates.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Google World Weather" 
        SizeToContent="WidthAndHeight" 
        WindowStartupLocation="CenterScreen"
        xmlns:local="clr-namespace:DataTemplates" >

    <!--Resources section-->
    <Window.Resources>

        <!--Styles-->
        <Style TargetType="Label">
            <Setter Property="FontSize" Value="24" />
            <Setter Property="Margin" Value="10,0,0,0" />
        </Style>

        <Style x:Key="stretched" TargetType="ListBoxItem">
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        </Style>

    </Window.Resources>

    <!--Command binding definition-->
    <Window.CommandBindings>
        <CommandBinding Command="Refresh" x:Name="cmdLoadWeatherForecast" CanExecute="cmdLoadWeatherForecast_CanExecute" Executed="cmdLoadWeatherForecast_Executed" />
    </Window.CommandBindings>

    <!--UI design - layout of individual controls-->
    <Grid x:Name="LayoutRoot">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <ListBox x:Name="weatherList" Grid.Row="0" ItemContainerStyle="{StaticResource stretched}" ItemsSource="{Binding WeatherInfo}" />

        <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" Margin="10" >
            <TextBox Text="Brighton UK" Name="txtLocation" Width="200" FontSize="20" Margin="10" FocusManager.FocusedElement="{Binding txtLocation}" />
            <Button IsDefault="True" Name="btnLoadForecast" Content="Load Weather Forecast"  Command="Refresh" Margin="0,10,10,10" Padding="10"/>
        </StackPanel>

    </Grid>
</Window>

4 个答案:

答案 0 :(得分:3)

除非ListBox在另一个DataContext中,否则您的代码应该有效。

<ListBox x:Name="weatherList" 
    Grid.Row="0" 
    ItemContainerStyle="{StaticResource stretched}" 
    ItemsSource="{Binding DataContext.WeatherInfo, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type yournamespace:MainWindow}}}" />

找出答案。

答案 1 :(得分:2)

谢谢大家的宝贵建议。我不知道输出窗口中显示的绑定错误,从那里我只有一个Google远离解决方案。

我遇到的问题是我试图绑定的WeatherInfo项目源是公共字段,而不是属性。因此,我可以简单地将WeatherInfo public ObservableCollection分配给列表框的itemssource,但我不能依赖数据绑定机制来定位DataContext中的WeatherInfo属性,因为WeatherInfo在技术上不是属性。添加{get;私有集;}到我的MainVM中的WeatherInfo声明使数据绑定按预期工作,我不必再将WeatherInfo对象作为列表框的ItemsSource分配给代码了。

答案 2 :(得分:1)

[编辑:感觉愚蠢]

好的,抱歉,我看到你在StartUp中...之前很快回答... MainWindow是ListBox所在的对象,对吗?

但是,我会检查一下,确保没有更接近ListBox(直接父级等)的DataContext有自己的。

答案 3 :(得分:1)

  1. 加载表单时,请检查 输出窗口,看是否有 任何绑定错误消息。

  2. 确保您的快捷方式 DataContext是正确的,是抛出一个 ListBox旁边的按钮, 在Window中将事件链接到它 代码隐藏并设置断点。 然后,当你到达所述断点 去你眼前的窗口偷看 通过强制转换进入DataContext 到ViewModel: (MainVM)DataContext

  3. WeatherInfo是否静止?

  4. 您可以发布您的MainVM对象代码吗?