0

私は WPF を試していて、以前に Silverlight でいくつかの作業を行い、DataContext、Data Binding、および 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# コードの抜粋に示されているように)、期待どおりにリストにデータが取り込まれません。

誰かが私に説明してもらえますか?なぜですか?

==編集==

メイン ウィンドウのすべての 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

4 に答える 4

4

皆様、貴重なご提案ありがとうございます。出力ウィンドウにバインディング エラーが表示されていることを認識していませんでした。そこから、解決策まで 1 Google しか離れていませんでした。

私が抱えていた問題は、バインドしようとしていた WeatherInfo 項目のソースが、プロパティではなくパブリック フィールドであったことです。したがって、WeatherInfo public ObservableCollection をリストボックスの itemssource に割り当てるだけで済みますが、WeatherInfo は技術的にはプロパティではないため、データ バインディング メカニズムを使用して DataContext 内の WeatherInfo プロパティを特定することはできませんでした。{get; の追加 private set;} を MainVM の WeatherInfo 宣言に追加すると、データ バインディングが期待どおりに機能するようになり、コードでリストボックスの ItemsSource として WeatherInfo オブジェクトを割り当てる必要がなくなりました。

于 2010-11-01T09:46:53.063 に答える
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}}}" />

調べるために。

于 2010-10-29T14:25:36.443 に答える
1

[編集:愚かだと感じる]

さて、申し訳ありませんが、あなたはスタートアップにいるようです...前にすぐに答えました...メインウィンドウはリストボックスが入っているオブジェクトですよね?

ただし、リストボックスに近いもの(直接の親など)に独自のDataContextがないことを確認します。

于 2010-10-29T14:21:12.320 に答える
1
  1. フォームをロードするときは、出力ウィンドウをチェックして、バインディング エラー メッセージがあるかどうかを確認します。

  2. DataContext が正しいことを確認する簡単な方法は、ListBox のすぐ隣にボタンをスローし、ウィンドウの分離コードでイベントをリンクし、ブレークポイントを配置することです。次に、上記のブレークポイントに到達したら、すぐに使用できるウィンドウに移動し、ViewModel にキャストして DataContext を調べます。 (MainVM)DataContext

  3. WeatherInfo は静的ですか?

  4. MainVM オブジェクト コードを投稿できますか?

于 2010-10-29T15:22:35.743 に答える