我正在尝试使用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>
答案 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)
加载表单时,请检查 输出窗口,看是否有 任何绑定错误消息。
确保您的快捷方式
DataContext是正确的,是抛出一个
ListBox旁边的按钮,
在Window中将事件链接到它
代码隐藏并设置断点。
然后,当你到达所述断点
去你眼前的窗口偷看
通过强制转换进入DataContext
到ViewModel:
(MainVM)DataContext
WeatherInfo是否静止?
您可以发布您的MainVM对象代码吗?