【问题标题】:BindingExpression path error in child usercontrols子用户控件中的 BindingExpression 路径错误
【发布时间】:2011-06-28 18:12:18
【问题描述】:

我正在开发一个基于 WPF/PRISM 的应用程序。父视图(用户控件)中有许多区域,子视图(用户控件)加载在这些区域中。当子视图被加载时,我可以看到控制台中打印的绑定错误。即使绑定的属性是子视图的视图模型的一部分,绑定分辨率似乎首先查看父视图的视图模型并引发此错误。该应用程序运行良好,我想知道我是否可以摆脱这些错误。

我已经设法在我编写的一个简单应用程序中重新创建了它。

C#

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
        InitializeComponent(); 
        this.DataContext = this; 
        this.Loaded += (o, e) => { this.layout.DataContext = new ViewModel(); }; 
    } 
} 

public class ViewModel 
{ 
    public ViewModel() 
    { 
        this.SampleText = "Sample"; 
    } 

    public string SampleText { get; set; } 
} 

XAML

<Window x:Class="DataBindingResolution.MainWindow" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase" 
        Title="MainWindow" Height="350" Width="525"> 
    <Grid x:Name="layout"> 
        <Grid.Resources> 
            <TextBlock x:Key="test" Text="{Binding SampleText}"/> 
        </Grid.Resources> 
        <Button Content="{StaticResource test}"/> 
    </Grid> 
</Window>

当您运行此示例时,您可以看到:

System.Windows.Data 错误:39: BindingExpression 路径错误: 'SampleText' 属性未找到 '对象' ''主窗口' (名称='')'。 绑定表达式:路径=示例文本; 数据项='主窗口'(名称=''); 目标元素是'TextBlock' (名称='');目标属性是“文本” (输入“字符串”)

即使按钮在其中正确显示文本“示例”,也会在控制台中打印。如何避免在控制台中打印此消息,我的应用程序会为每个加载的子视图打印 25 个以上的错误。

【问题讨论】:

    标签: c# wpf data-binding


    【解决方案1】:

    您可能应该将两个 ViewModel 分成两个类。然后让父 ViewModel 引用子 ViewModel。其他的一切都可以通过绑定来完成。

    public partial class MainWindow : Window     
    {    
        public MainWindow()         
        {             
            InitializeComponent();             
            this.DataContext = new ParentViewModel();             
        }        
    }  
    
    public class ParentViewModel     
    {
        public ViewModel()        
        { 
            this.Child = new ChildViewModel();       
        }         
    
        public ChildViewModel Child { get; set; }     
    }  
    
    public class ChildViewModel     
    {
        public ViewModel()        
        { 
            this.SampleText = "Sample";         
        }         
    
        public string SampleText { get; set; }     
    }
    

    这个简化的 Xaml 想要:

    <Window>     
     <Grid x:Name="layout" DataContext="{Binding Child}">
        <Button Content="{Binding SampleText}"/>
        </Grid> 
    </Window>
    

    【讨论】:

    • Parent 不知道正在加载的子项都是注入视图的棱镜区域。
    • 在这种情况下,每个子视图都是独立的。创建视图的过程应该将 ViewModel 注入到子视图中。如果您使用 Unity 来解析视图和视图模型,则可以一步完成。见wintellect.com/CS/blogs/sloscialo/archive/2011/05/19/…
    • 太棒了!它从未想过它与视图模型分辨率有关。谢谢。
    【解决方案2】:

    您需要在 Loaded 事件处理程序中设置 DataContext 吗?

    我稍微移动了代码并阻止了消息:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new ViewModel();
            //this.Loaded += (o, e) => { this.layout.DataContext = new ViewModel(); };
        }
    }
    
    public class ViewModel
    {
        public ViewModel()
        {
            this.SampleText = "Sample";
        }
        public string SampleText { get; set; }
    } 
    

    【讨论】:

    • 这实际上模拟了我的应用程序中发生的情况。 MainWindow 是我的父视图,具有自己的 ViewModel,网格是具有自己的视图模型的子视图。我无法将子视图模型分配给父视图模型,反之亦然。
    • 我想知道这是否与您与 Prism 一起使用的依赖注入容器有关。您使用的是 Unity 还是其他?
    • Bootstrapper 并没有做太多与个别视图相关的事情,这些都注册在各自的模块中。你能告诉我你要去哪里吗
    猜你喜欢
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 2011-12-23
    • 1970-01-01
    • 2015-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多