WPF窗口未使用XAML中的绑定更新

斯拉博伊

有人可以解释一下这是怎么回事吗?我是WPF的新手,并通过绑定将Forms项目迁移到WPF。我正在使用AvalonDock,但没有直接绑定到任何AvalonDock控件。这是几个摘录。为了简洁起见,我删除了很多内容,但如果您需要查看其他内容,请告诉我。

编辑:这两个StackPanels只是测试...试图弄清楚这些东西。
EDIT2:我最终尝试做MVVM;我只需要对绑定有一个更好的了解,所以我知道如何构造它。
EDIT3:请参阅文章底部。

问:第一个StackPanel完全不更新,更不用说更改后进行更新。我已经尝试设置DataContextStackPanelGridTextBlock我究竟做错了什么?

问:当父网格绑定在后面的代码中但仅当绑定在您看到它的地方(而不是在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";
}

EntityEntityViewModel实施INotifyPropertyChanged,它与第二个都很好StackPanel调用的按钮button_Click()仅用于测试绑定。EntityViewModel几乎只是Entity遍历该ActiveEntity属性,并有助于读取中的collections-of-collections Entity

编辑3:

我也尝试了一些资源。这是我做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}" />
米歇尔·西尚(Michal Ciechan)

您的第一个堆栈面板不起作用,因为数据上下文是继承的。因此,一旦将Grid的DataContext更改为ActiveEntity对象,则在第一个数据上下文中的文本块上的绑定会将TextBlock的datacontext设置为ActiveEntity当前数据上下文上的,该文本已经是ActiveEntity(因此ActiveEntity.ActiveEntity)并且可以尝试绑定到该标签的属性。例如ActiveEntity.ActiveEntity.Label

单击之前,您正在将该窗口的DataContext设置为“ this”,我假设它不是ViewModel,是后面的代码吗?

如果您使用的是MVVM,

你应该有这样的东西

private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
    SelectedEntityViewModel = new ViewModel.EntityViewModel();
    this.DataContext = SelectedEntityViewModel;
    ImportEntityXML_Click(null, null); //skips clicking the menus
}

或其他提供所有必要数据的ViewModel。

通常,您会有一个MainWindowViewand MainWindowViewModel,至少这是约定,通常您只需在构造函数中设置一次窗口的数据上下文(可以在Loaded处理程序中设置),在大多数情况下,您无需手动更改后面代码中的任何框架元素。

编辑:示例代码:

MainWindow.xaml

<Window x:Class="SO27760357.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="300" Width="300">
    <Grid>
        <StackPanel Orientation="Vertical">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Label" />
                <TextBlock Text="{Binding ActiveEntity.Label}"/>
            </StackPanel>

            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Label Again" />
                <TextBlock Text="{Binding ActiveEntity.Label}" />
            </StackPanel>
        </StackPanel>
    </Grid>
</Window>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new MainWindowViewModel();
    }
}

MainWindowViewModel.cs(为简单起见,省略了INotifyPropertChanged)

public class MainWindowViewModel
{
    public EntityViewModel ActiveEntity { get; set; }
}

EntityViewModel.cs(为简单起见,省略了INotifyPropertChanged)

public class EntityViewModel
{
    public string Label { get; set; }
}

如您所见,我将Window的DataContext设置为MainViewModel,因此DataContext(所有绑定的根)是MainViewModel,每个TextBlock需要首先访问该ActiveEntity属性,然后才能访问属性Label

另一个选择是,如果您给我们的主堆栈面板中的所有内容都将绑定到ActiveEntity,则可以更改该StackPanel的DataContext,将其绑定到ActiveEntity,因此其所有子级datacontext也将是该对象。

    <StackPanel Orientation="Vertical"
                **DataContext="{Binding ActiveEntity}"**>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Label" />
            <TextBlock **Text="{Binding Label}"**/>
        </StackPanel>

        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Label Again" />
            <TextBlock **Text="{Binding Label}"** />
        </StackPanel>
    </StackPanel>

编辑2-建议

您应该避免按名称引用对象,并且如果有的话,在其背后的代码中也应尽量少包含逻辑。对于大多数简单的屏幕,除了DataContext的初始绑定之外,不需要在代码中包含任何其他内容(如果您没有创建+设置Windows的DataContext的窗口服务)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

XAML中的WPF ListView绑定ItemsSource

来自分类Dev

XAML中的WPF文本块绑定

来自分类Dev

WPF ListBox属性绑定未更新

来自分类Dev

WPF绑定:如何在UserControl XAML中设置绑定源

来自分类Dev

Combox在WPF中未更新

来自分类Dev

SelectedItem在WPF中的ListView中未绑定

来自分类Dev

WPF DataGrid中的按钮绑定不会更新

来自分类Dev

WPF文本框未使用数据绑定,iNotifyPropertyChanged和PropertyChanged触发器更新

来自分类Dev

当ObservableCollection值更新时,WPF Datagrid绑定未更新

来自分类Dev

使用ObservableCollection更新对CollectionChanged的XAML绑定

来自分类Dev

不使用XAML进行绑定[WPF]

来自分类Dev

WPF XAML绑定不会更新

来自分类Dev

wpf绑定中的源代码更新

来自分类Dev

WPF绑定:如何在UserControl XAML中设置绑定源

来自分类Dev

XAML绑定未反映ViewModel中的更改

来自分类Dev

WPF XAML数据绑定

来自分类Dev

WPF / XAML绑定:使用实际的DataContext

来自分类Dev

当ObservableCollection值更新时,WPF Datagrid绑定未更新

来自分类Dev

使用ObservableCollection更新对CollectionChanged的XAML绑定

来自分类Dev

绑定到静态属性时,ListView在WPF中未更新

来自分类Dev

不使用XAML进行绑定[WPF]

来自分类Dev

WPF中的XAML弹出窗口溢出

来自分类Dev

如何在 C# 中使用 WPF 绑定 Xaml 中的动态值

来自分类Dev

Wpf 数据绑定文本块未更新

来自分类Dev

wpf 中多个窗口上的键绑定

来自分类Dev

WPF 绑定正确,但窗口不更新

来自分类Dev

使用 DevExpress 在 WPF 中未显示窗口

来自分类Dev

使用 INotifyPropertyChanged 的 WPF Xaml 绑定类实例

来自分类Dev

WPF 用户控件属性未绑定或更新