ListBox.ItemsSource {Binding ...} 不起作用,但如果我在代码中设置 ItemsSource,那就太棒了!

发布于 2024-09-29 23:20:22 字数 3061 浏览 0 评论 0原文

我正在尝试 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();
}

当我像这样运行应用程序时,一切都很好,主窗口上的列表框显示在 WeatherInfo ObservableCollection 中找到的项目MainVM 就像它应该的那样。

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

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

尽管我确实设置了MainWindow 到 MainVM 的实例(如 C# 代码摘录中所示)。

有人可以向我解释一下为什么吗?

==编辑==

我的所有主窗口的 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>

I am experimenting with WPF and I came across a problem I can't seem to figure out although I have done some work with Silverlight previously and used DataContexts, Data Bindings and INPC successfully. This time I am stuck...

I am using this code to create an instance of the application's main window:

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();
}

When I run the application like this, all is fine, the ListBox on the main window displays the items found in the WeatherInfo ObservableCollection of the MainVM like it should.

However, when I comment the line out and then go into my main window's XAML, and setup the ItemsSource property of the weatherList ListBox in XAML like so:

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

The list does not get populated as I would expect, although I do set the DataContext of the MainWindow to an instance of the MainVM (as shown in the C# code excerpt).

Could someone please explain to me, WHY?

==EDIT==

All of my Main Window's 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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

屌丝范 2024-10-06 23:20:22

谢谢大家提出的宝贵建议。我不知道“输出”窗口中显示了“绑定错误”,从那里我只需谷歌一下就能找到解决方案。

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

Thank you all for your valuable suggestion. I wasn't aware of the Binding Errors being displayed in the Output window and from there I was only one Google away from the solution.

The problem I had was that the WeatherInfo items source I was trying to bind to was a public field, not a property. Therefore, I could simply assign the WeatherInfo public ObservableCollection to the listbox's itemssource but I could not rely on the data binding mechanism to locate the WeatherInfo property in the DataContext, as WeatherInfo was not technically a property. Adding {get; private set;} to the WeatherInfo declaration in my MainVM made the data binding work as expected and I don't have to assign WeatherInfo object as ItemsSource of the listbox in code any more.

对你的占有欲 2024-10-06 23:20:22

除非 ListBox 在另一个 DataContext 中,否则您的代码应该可以工作。

尝试

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

找出答案。

Your code should work unless ListBox is in another DataContext.

try

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

to find out.

诠释孤独 2024-10-06 23:20:22

[编辑:感觉很愚蠢]

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

但是,我会检查以确保靠近 ListBox(直接父级等)的任何东西都没有自己的 DataContext。

[Edit: Feel Stupid]

Okay, sorry, I see that you're in the StartUp...answered to quickly before...MainWindow IS the object that the ListBox is in, correct?

I would check, however, to make sure that nothing closer to the ListBox (direct parent, etc.) has a DataContext of its own.

我早已燃尽 2024-10-06 23:20:22
  1. 当您加载表单时,请检查
    输出窗口看是否有
    任何绑定错误消息。

  2. 一个很好的快速方法来确保您
    DataContext 正确的是抛出一个
    列表框旁边的按钮,
    在窗口中将事件链接到它
    代码隐藏并放置断点。
    然后当你到达所说的断点时
    到你眼前的窗口看一眼
    通过将其强制转换到您的 DataContext 中
    到视图模型:
    (MainVM)DataContext

  3. WeatherInfo 是否静态?

  4. 您可以发布您的 MainVM 目标代码吗?

  1. When you load the form check the
    output window to see if there are
    any binding error messages.

  2. A nice quick way to ensure you're
    DataContext is correct is to throw a
    button right next to the ListBox,
    link an event to it in the Window's
    codebehind and put a breakpoint.
    Then when you reach said breakpoint
    go to your immediate window and peek
    into your DataContext by casting it
    to the ViewModel:
    (MainVM)DataContext

  3. Is WeatherInfo static or not?

  4. Can you post your MainVM object code?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文