Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF窗口未使用XAML中的绑定进行更新_C#_Wpf - Fatal编程技术网

C# WPF窗口未使用XAML中的绑定进行更新

C# WPF窗口未使用XAML中的绑定进行更新,c#,wpf,C#,Wpf,有人能解释一下这是怎么回事吗?我是WPF新手,正在使用绑定将表单项目迁移到WPF。我使用的是AvalonDock,但我没有直接绑定到任何AvalonDock控件。这里有几段摘录。为了简洁起见,我删除了很多内容,但如果您需要查看其他内容,请告诉我 编辑:这两个StackPanel只是测试。。。试图弄明白这件事。 EDIT2:我最终会尝试做MVVM;我只需要更好地处理绑定,这样我就知道如何构造它。 EDIT3:见文章底部 问:第一个StackPanel根本不更新,更不用说更改后的更新了。我已尝试在S

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

编辑:这两个StackPanel只是测试。。。试图弄明白这件事。
EDIT2:我最终会尝试做MVVM;我只需要更好地处理绑定,这样我就知道如何构造它。
EDIT3:见文章底部

问:第一个
StackPanel
根本不更新,更不用说更改后的更新了。我已尝试在
StackPanel
Grid
TextBlock
中设置
DataContext
。我做错了什么

问:当父网格在代码隐藏中绑定时,第二种方法可以正常工作,但只有在您看到它的地方绑定,而不是在
MainWindow\u Loaded()
方法中绑定。这里有什么不同

我已经阅读了好几篇教程以及很多类似的问题,但是没有任何东西能帮助我理解这里的区别和我遗漏了什么


private void主窗口\u已加载(对象发送方,路由目标)
{
this.DataContext=this;
SelectedEntityViewModel=new ViewModel.EntityViewModel();
ImportEntityXML_单击(null,null);//跳过单击菜单
}
私有void importentyxml\u单击(对象发送方,路由目标)
{
//省略了OpenFileDialog和XmlReader的内容
xmlreader=新的xmlreader(dlg.FileName);
Add(xmlreader.ReadEntityFromXML());
SimulatedEntitySelection(Entities.ElementAt(0));//尚未为此构建任何UI内容
}
私有所有权选择(实体ent)
{
选择edentityviewmodel.ActiveEntity=ent;
gridTest.DataContext=SelectedEntityViewModel.ActiveEntity;
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
选择edentityviewmodel.ActiveEntity.Label=“测试”;
}
Entity
EntityViewModel
实现
INotifyPropertyChanged
,第二个
StackPanel
可以正常工作。调用
button\u Click()
的按钮仅用于测试绑定
EntityViewModel
几乎只是通过
ActiveEntity
属性包装
Entity
,并帮助读取
Entity
中的集合集合

EDIT3:

我也尝试了一些资源。下面是我如何创建ObjectDataProvider的:


它确实有效。您可能正在更新错误的viewmodel

DataContext
中定义viewmodel后,必须通过以下方式访问它:

private void button_Click(object sender, RoutedEventArgs e) 
{
    var myModel = (ViewModel.EntityViewModel)(yourStackPanelName.DataContext);
    myModel.ActiveEntity.Label = "test";
}

第一个堆栈面板不工作,因为数据上下文是继承的。因此,一旦将网格的DataContext更改为
ActiveEntity
对象,第一个数据上下文中文本块上的绑定将把TextBlock的DataContext设置为当前DataContext上的
ActiveEntity
,它将已经是
ActiveEntity
(因此
ActiveEntity.ActiveEntity
)然后尝试绑定到该属性上的Label属性,例如
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

您通常会有一个
MainWindowView
MainWindowViewModel
,至少这是惯例,并且通常您会在构造函数中设置一次窗口的datacontext(您可以在加载的
处理程序中执行),在大多数情况下,不需要手动更改代码隐藏中任何框架元素的DataContext

编辑:示例代码:

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>
MainWindowViewModel.cs(为简单起见,省略了INotifyPropertChanged)

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

如您所见,我正在将窗口的DataContext设置为MainViewModel,因此DataContext(所有绑定的根)是MainViewModel,每个文本块需要首先访问
ActiveEntity
属性,然后才能访问
标签
项目

另一个选项是,如果您提供给我们的主堆栈面板中的所有内容都将绑定到ActiveEntity,那么您可以更改该堆栈面板的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的窗口服务)

哦,天哪……在试图让它工作的所有愤怒的阴霾中,我确实忘记了为第一个StackPanel设置这个。我不得不承认,他关于DataContext继承的说明确实为我澄清了整个问题。哦,天哪,你击中了我的头。谢谢!你指出了我在第一个StackPanel上的问题,但你确实指出了arify数据上下文的继承
public class MainWindowViewModel
{
    public EntityViewModel ActiveEntity { get; set; }
}
public class EntityViewModel
{
    public string Label { get; set; }
}
    <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>