【发布时间】:2015-01-03 22:46:59
【问题描述】:
有人可以解释一下这里发生了什么吗?我是 WPF 的新手,我正在通过绑定将我的 Forms 项目迁移到 WPF。我正在使用 AvalonDock,但我没有直接绑定到任何 AvalonDock 控件。这里有几个摘录。为简洁起见,我删除了很多内容,但如果您需要查看其他内容,请告诉我。
编辑:这两个 StackPanel 只是测试......试图弄清楚这些东西。
EDIT2:我最终会尝试做 MVVM;我只需要更好地处理绑定,以便知道如何构建它。
EDIT3:见帖子底部。
Q:第一个StackPanel根本不更新,更别提更新了。我尝试在StackPanel、Grid 和TextBlock 中设置DataContext。我做错了什么?
问:当父网格绑定在后面的代码中时,第二个工作正常,但前提是绑定在您看到它的位置,而不是在MainWindow_Loaded() 方法中。这里有什么不同?
我在这里阅读了几个教程以及许多类似的问题,但没有什么能帮助我理解这里有什么区别以及我缺少什么。
<Window x:Class="TestUIWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ad="http://schemas.xceed.com/wpf/xaml/avalondock"
Title="MainWindow" Height="768" Width="1024"
Loaded="MainWindow_Loaded"
xmlns:vm="clr-namespace:TestUIWPF.ViewModel"
>
<!-- lots excluded for brevity. there are no Window.Resources -->
<ad:LayoutAnchorable Title="Test" >
<Grid x:Name="gridTest">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<StackPanel.DataContext>
<vm:EntityViewModel />
</StackPanel.DataContext>
<TextBlock Text="Label" />
<TextBlock DataContext="{Binding ActiveEntity}" Text="{Binding Path=Label}" />
</StackPanel>
<StackPanel Orientation="Horizontal" >
<TextBlock Text="Label Again" />
<TextBlock Text="{Binding Path=Label}" />
</StackPanel>
</StackPanel>
</Grid>
</ad:LayoutAnchorable>
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = this;
SelectedEntityViewModel = new ViewModel.EntityViewModel();
ImportEntityXML_Click(null, null); //skips clicking the menus
}
private void ImportEntityXML_Click(object sender, RoutedEventArgs e)
{
//omitted OpenFileDialog and XmlReader stuff
xmlreader = new XmlReader(dlg.FileName);
Entities.Add(xmlreader.ReadEntityFromXML());
SimulatedEntitySelection(Entities.ElementAt(0)); //haven't built any of the UI stuff for this yet
}
private void SimulatedEntitySelection(Entity ent)
{
SelectedEntityViewModel.ActiveEntity = ent;
gridTest.DataContext = SelectedEntityViewModel.ActiveEntity;
}
private void button_Click(object sender, RoutedEventArgs e)
{
SelectedEntityViewModel.ActiveEntity.Label = "test";
}
Entity 和 EntityViewModel 实现 INotifyPropertyChanged 并且它与第二个 StackPanel 一起工作得很好。调用button_Click() 的按钮仅用于测试绑定。 EntityViewModel 几乎只是通过 ActiveEntity 属性包装 Entity 并帮助读取 Entity 中的集合。
EDIT3:
我还尝试了一些资源。以下是我执行 ObjectDataProvider 的方法:
<Window.Resources>
<ObjectDataProvider x:Key="testVM" ObjectType="{x:Type vm:EntityViewModel}" />
<vm:EntityViewModel x:Key="SelEntVM" />
</Window.Resources>
<!-- .... -->
<StackPanel.DataContext>
<Binding Source="{StaticResource testVM}" />
</StackPanel.DataContext>
<TextBlock Text="Label" />
<TextBlock Text="{Binding Path=ActiveEntity.Label}" />
【问题讨论】: