【问题标题】:Public Property Data Binding failing in XamlXaml 中的公共属性数据绑定失败
【发布时间】:2013-08-08 15:23:32
【问题描述】:

我的文件隐藏代码具有其对应的视图模型作为我的一个 Windows 的公共属性。我尝试将我的 ViewModel 与 XAML 中的 UI 元素进行数据绑定,但我总是收到错误消息。但是,当我尝试使用代码创建数据绑定时,它可以正常工作。我真的很困惑为什么会发生这种情况,并希望得到一些关于我做错了什么的指导。

场景 1 - 在 xaml 中完成数据绑定失败

ProductInfoWindow.xaml:

<Window ...>
    <Grid Name="grdProd" DataContext="{Binding RelativeSource={RelativeSource Self}, Path=ViewModel}">
        <TextBox Name="txtName" Text="{Binding Product.Name}" />
    </Grid>
</Window>

ProductInfoWindow.xaml.cs:

public partial class ProductInfoWindow : Window
{
    public ProductInfoViewModel ViewModel { get; set; }

    public ProductInfo()
    {
        ViewModel = new ProductInfoViewModel(...);
    }
}

输出窗口中的错误消息:

System.Windows.Data Error: 40 : BindingExpression path error: 'ViewModel' property not 
found on 'object' ''Grid' (Name='grdProd')'. BindingExpression:Path=ViewModel; 
DataItem='Grid' (Name='grdProd'); target element is 'Grid' (Name='grdProd'); target 
property is 'DataContext' (type 'Object')

场景 2 - 在代码中完成数据绑定工作

ProductInfoWindow.xaml:

<Window ...>
    <Grid Name="grdProd">
        <TextBox Name="txtName" Text="{Binding Product.Name}" />
    </Grid>
</Window>

ProductInfoWindow.xaml.cs:

public partial class ProductInfoWindow : Window
{
    public ProductInfoViewModel ViewModel { get; set; }

    public ProductInfo()
    {
        ViewModel = new ProductInfoViewModel(...);
        grdProd.DataContext = ViewModel;
    }
}

编辑 (09/08/2013)

ProductInfoViewModel.cs

public class ProductInfoViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, e);
    }

    private Product m_product;

    public Product Product
    {
        get
        {
            return m_product;
        }

        set
        {
            m_product = value;
            OnPropertyChanged(new PropertyChangedEventArgs("Product"));
        }
    }

    public ProductInfoViewModel(...)
    {
        Product = new Product(...);
    }
}

【问题讨论】:

  • 你得到什么错误信息?
  • @GrandMasterFlush,我在“输出窗口中的错误消息”小节下的场景 1 末尾添加了错误消息。

标签: wpf xaml data-binding


【解决方案1】:

您的错误消息告诉您在Grid 'grdProd' 上找不到ViewModel 属性,这是公平的,因为您的Viewmodel 是在ProductInfoWindow 上定义的公共属性类。

尝试将Datacontext 设置为Window 级别(修改您的示例):

<Window DataContext="{Binding RelativeSource={RelativeSource Self}, Path=ViewModel}" ...>
    <Grid Name="grdProd"> 
        <TextBox Name="txtName" Text="{Binding Product.Name}" />
    </Grid>
</Window>

【讨论】:

  • 我不再收到任何错误。但是没有一个 UI 控件显示任何信息。我仔细检查了我是否完全按照您所说的进行了修复。你的回答很有道理,所以我不确定为什么它没有发生。
  • 您的 Viewmodel 在哪里初始化?如果在创建Window 之后发生初始化,则 UI 不一定会更新,您需要实现 INotifyPropertyChanged 以通知您的 UI 正在发生对绑定对象的更改。例如stackoverflow.com/questions/1315621/…
  • 克里斯,我在上面的“编辑”部分添加了我对 ProductInfoViewModel 的实现。我昨晚尝试通过 ViewModel 进行调试,这就是我发现的。我的 PropertyChanged 事件处理程序始终为空。这让我感到惊讶,因为我认为 xaml "Window DataContext=..." 行会导致 PropertyChanged 事件处理程序被初始化或其他什么。
  • 如果你将你的窗口绑定到一个空的DataContext,它稍后会被初始化,你的Window不会知道它的ViewModel对象已经改变(并且不会更新DataContext。您可以在Window 上实现INotifyPropertyChanged,但这不是一个很好的解决方案。最好在创建视图之前实例化您的ViewModel(您可以在调用@987654339 之前执行此操作@ 在你的 Window 构造函数中。
猜你喜欢
  • 2011-06-12
  • 1970-01-01
  • 1970-01-01
  • 2023-01-10
  • 1970-01-01
  • 1970-01-01
  • 2018-05-09
  • 2014-08-11
  • 1970-01-01
相关资源
最近更新 更多