ListBox.ItemsSource {Binding ...} не работает, но если я установлю ItemsSource в коде, это все будет здорово! - PullRequest
0 голосов
/ 29 октября 2010

Я экспериментирую с 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 в главном окне отображает элементы, найденные в WeatherInfo ObservableCollection MainVM, как и должно быть.

Однако, когда я комментирую строку, а затем захожу в XAML моего главного окна и настраиваю свойство ItemsSource WeatherBist ListBox в XAML следующим образом:

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

Список заполняется не так, как я ожидал, хотя я установил для DataContext MainWindow экземпляр 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 ]

3 голосов
/ 29 октября 2010

Ваш код должен работать, если ListBox не находится в другом DataContext.

попробовать

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

чтобы узнать.

2 голосов
/ 01 ноября 2010

Спасибо всем за ваше ценное предложение. Я не знал об ошибках привязки, отображаемых в окне «Вывод», и оттуда я был всего в одном Google от решения.

Проблема, с которой я столкнулся, заключалась в том, что источник элементов WeatherInfo, к которому я пытался привязаться, был открытым полем, а не собственностью. Поэтому Я мог бы просто назначить общедоступную ObservableCollection WeatherInfo для источника элементов списка, но я не мог полагаться на механизм привязки данных, чтобы найти свойство WeatherInfo в DataContext, так как WeatherInfo технически не был свойством . Добавление {получить; закрытый набор;} для объявления WeatherInfo в моем MainVM связывание данных сработало, как и ожидалось, и мне больше не нужно назначать объект WeatherInfo как ItemsSource списка в коде.

1 голос
/ 29 октября 2010
  1. Когда вы загружаете форму, проверьте окно вывода, чтобы увидеть, если есть любые сообщения об ошибках привязки.

  2. Хороший быстрый способ убедиться, что вы DataContext является правильным, чтобы бросить кнопка прямо рядом с ListBox, привязать событие к нему в окне зашифровать и поставить точку останова. Затем, когда вы достигаете указанной точки останова зайдите в ваше ближайшее окно и загляните в ваш DataContext, приведя его в ViewModel: (MainVM)DataContext

  3. Является ли WeatherInfo статическим или нет?

  4. Можете ли вы опубликовать свой объектный код MainVM?

1 голос
/ 29 октября 2010

[Редактировать: Чувствую себя глупо]

Хорошо, извините, я вижу, что вы в автозагрузке ... быстро ответили перед ... MainWindow - это объект, в котором находится ListBox, верно?

Я бы, однако, проверил, чтобы ничто ближе к ListBox (непосредственный родитель и т. Д.) Не имело собственного DataContext.

...