XAML内联数据绑定不起作用;绑定背后的代码

时间:2010-07-09 17:22:21

标签: c# wpf data-binding user-controls

问候人们! 我遇到了WPF数据绑定的问题,我希望你可以帮忙。我是WPF的新手,但是他是一名经验丰富的开发人员(VB 3.0-6.0,C#)。

以下是该方案: 我有一个名为MasterPartsData的C#项目,它包含许多类来代表不同类型的部件(电容器,二极管等)。它们继承自名为clsPart的基类。

我有另一个C#WPF项目,其中包含WPF UserControls(以及MainWindow),可直观地表示存储在单个MasterPartsData(MPD)对象中的值。我在usercontrol中创建了一个私有字段来保存带有getter和setter的对象。

如果我在填充对象的setter中显式创建了一个绑定:

_capacitor = value;
Binding binding = new Binding();
binding.Source = _capacitor;
binding.Path = new PropertyPath("C0uf");
this.txtC0uf.SetBinding(TextBox.TextProperty, binding);

(_capacitor是私有对象变量,C0uf是属性名称) 值正确显示。

但是我不希望在后面的代码中显式创建每个绑定。我的偏好是在XAML中内联创建绑定,可能使用指向对象的DataContext。

不幸的是,我尝试过的每种不同的排列都无法奏效;文本框不显示数据。

我有几个怀疑: 1)绑定是正确的,但需要刷新文本框。 2)私有变量和属性之间的绑定混淆。 3)可能是在不同的项目中定义类的事实导致问题。 4)我生气了,应该在有人受伤前检查自己是否有庇护。 :)

我们非常感谢您提供的任何帮助。我非常乐意添加更多信息,但不想用页面和页面来源混淆问题。

2 个答案:

答案 0 :(得分:4)

关于你的怀疑:

1)我认为TextBox的默认绑定行为是TwoWay,带有LostFocus更新触发器,这意味着您的UI焦点必须在绑定之前更改为另一个控件如果在UI中进行了更改,则会更新。

如果在代码中进行了更改,则需要引发NotifyPropertyChanged事件,以便绑定系统查看它。

2)这可能不是这种情况,但它给人的印象是你试图在你的UserControl属性上设置绑定,这不是数据绑定设计用于这种特殊类型的方式用例。您想要的是将非UI 类中的数据绑定到UserControl上的依赖项属性。

3)只要您的UI项目引用了您的类,这就无所谓了。

4)这是人们在开始使用XAML和WPF时的常见反应。这就像没有被交给一盒乐高积木,你刚拿到一台没有足够指示的注塑机,不是吗?

总的来说,这可能是您需要检查设计的情况; “Model-View-ViewModel”模式的元素将派上用场。如果您对此不熟悉,那么您可以在其中引入“ViewModel”类,也许您可​​以将其称为MasterPartsVM,其中包含INotifyPropertyChanged的实现。

DataContext的{​​{1}}将设置为此UserControl课程。

使用一些通用名称的简短代码示例。给定一个ViewModel类,其后备类如下:

MasterPartsVM

基本UserControl的XAML如下所示:

class PartViewModel : INotifyPropertyChanged
{

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

    public PartClass Data { get; set; }

    public String SomeVMProperty
    {
        get { return Data.SomeProperty; }

        set
        {
            if (Data.SomeProperty != value)
                Data.SomeProperty = value;
            this.PropertyChanged(this, new PropertyChangedEventArgs("SomeVMProperty"));
        }
    }

}

class PartClass
{
    public string SomeProperty { get; set; }
}

要将数据类连接到此UserControl,请设置UserControl的DataContext属性。如果你在代码中执行此操作,则需要引用用户控件和ViewModel,然后设置属性:

<UserControl x:Class="WpfApplication1.PartUserControl"
            ... >
    <Grid>
        <TextBox Text="{Binding SomeVMProperty}" Margin="68,77,104,176" />
    </Grid>
</UserControl>

这些代码组合应该可以生成一个文本框,其MyUserControlInstance.DataContext = new PartViewModel(); // or some existing PartViewModel 属性每次更改Text属性时都会更改。

答案 1 :(得分:1)

在基本绑定方案中,如果您的类看起来像这样

public class MasterPartsData
{
    private string _c0uf;

    public string C0uf
    {
        get { return _c0uf;}
        set { _c0uf = value;}
    }

    public MasterPartsData()
    {
        C0uf = "Hello World!";
    }
}

你的XAML看起来像这样

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="MainWindow" >
    <Window.DataContext>
        <local:MasterPartsData />
    </Window.DataContext>

    <Grid>
        <TextBlock Text="{Binding Path=C0uf}" />
    </Grid>
</Window>

注意,有许多不同的方法来设置DataContext,您不一定只需要在XAML中执行此操作

此外,通常您的MasterDataParts类将实现INotifyPropertyChanged