WPF数据绑定到复合类的模式? [英] WPF databinding to composite class patterns?

查看:145
本文介绍了WPF数据绑定到复合类的模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了WPF的第一次,我与如何控件绑定到建成使用其他物体组成的类挣扎。举例来说,如果我有一个是建立两个独立的类类比较(注:为清楚起见,留下了各种元素):

I am trying out WPF for the first time and I am struggling with how to bind controls to a class that is built up using composition of other objects. For example, If I have class Comp that is built up of two separate classes (note various elements left out for clarity):

class One {
   int _first;
   int _second;
}

class Two {
   string _third;
   string _fourth;
}

class Comp {
   int _int1;
   One _part1;
   Two _part2;
}

现在我明白,我可以很容易地绑定_int1使用获取的定义比较。但是,我怎么绑定的元素_part1._first,_part1._second。我有在类比较级揭露他们干将?或者我可以在复合类中揭露它们,并使用指向他们的结合路径?又如何与设置属性这项工作?

Now I understand that I can easily bind _int1 using a "get" defined in Comp. But how do I bind to the elements _part1._first, _part1._second. Do I have expose "getters" for them at the class Comp level? or can I expose them within the composite classes and use a binding path that points to them? And how does this work with setting the properties?

因此,这是模式?

....
<TextBlock Name="txtBlock" Text="{Binding Path=Third}" />    
....

class One {
   int _first;
   int _second;
}

class Two {
   string _third;
   string _fourth;
}

class Comp {
   int _int1;
   One _part1;
   Two _part2;

   int Int1 { get { return _int1; } set { _int1 = value; } }
   int First { get { return _part1._first; }  set { _part1._first = value; } }
   int Second { get { return _part1._second; } set { _part1._second = value; } }
   string Third { get { return _part2._third; }  set { _part2._third = value; } }
   string Fourth { get { return _part2.fourth; }  set { _part2._fourth = value; } }
}

...
Comp oComp = new Comp();
txtBlock.DataContext = oComp;
...

或者是这种模式呢? (这里我不知道要放什么东西的路径)

Or is this the pattern? (where I am not sure what to put for the path)

....
<TextBlock Name="txtBlock" Text="{Binding Path=_part2.Third}" />    
....

class One {
   int _first;
   int _second;
   int First { get { return _first; }  set { _first = value; } }
   int Second { get { return _second; }  set { _second = value; } }
}

class Two {
   string _third;
   string _fourth;
   string Third { get { return _third; } set { _third = value; } }
   string Fourth { get { return _fourth; } set { _fourth = value; } }
}

class Comp {
   int _int1;
   One _part1;
   Two _part2;

   int Int1 { get { return _int1; } }
}

...
Comp oComp = new Comp();
txtBlock.DataContext = oComp;
...



还是我对我的方式来重塑MV-VM(这?我慢慢开始领悟)

Or am I on on my way to reinvent M-V-VM (which I am slowly starting to comprehend)?

....
<TextBlock Name="txtBlock" Text="{Binding Path=Third}" />    
....

class One {
   int _first;
   int _second;
}

class Two {
   string _third;
   string _fourth;
}

class Comp {
   int _int1;
   One _part1;
   Two _part2;

}

class CompView {
   Comp _comp;

   CompView( Comp comp ) {
      _comp = comp;
   }

   int Int1 { get { return _comp._int1; } set { _comp._int1 = value; } }
   int First { get { return _comp._part1._first; }  set { _comp._part1._first = value; } }
   int Second { get { return _comp._part1._second; } set { _comp._part1._second = value; } }
   string Third { get { return _comp._part2._third; }  set { _comp._part2._third = value; } }
   string Fourth { get { return _comp._part2.fourth; }  set { _comp._part2._fourth = value; } }
 }

...
Comp oComp = new Comp();
CompView oCompView = new CompView( oComp );
txtBlock.DataContext = oCompView;
...



所以,我应该怎么做事情?如果是第一或第三的模式的话,好像我必须采取一切我可爱的(不同的)层次的数据和英镑下来到一台配置这样我就可以把它绑定到UI元素。这是它如何发生的,或者是有一个更好的方法(第二个模式?)

So how should I do things? If it is the first or the third pattern, then it seems that I have take all of my lovely (disparate) hierarchal data and pound it down to a flat configuration so I can bind it to the UI elements. Is this how it has to happen, or is there a better way (second pattern??)

修改

我离开了,我真的很想双向绑定的问题。所以属性访问器真的应该有get和set。

I left out of the question that I really want two way binding. So the property accessors really should have get and set.

修改

更新我的伪代码,以显示制定者以及干将

Updated my pseudo code to show setters as well as getters

修改

我跟着通过马克和Julien和实施制定者提供,很高兴与结果的格局。出于某种原因,我相信自己,一个属性的设置不会随之回落到最终实体的所有道路。

I followed through the pattern provided by Mark and Julien and implemented setters and was happy with the result. For some reason I convinced myself that the setting of a property would not follow all the way down to the final entity.

推荐答案

数据通过属性绑定的工作,这样你就不会在你的绑定,例如使用任何成员变量:

Data Binding works through properties, so you won't use any of the member variables in your Binding, eg:

int _first
public int First { get { return _first; } }

您将使用第一,而不是_first为绑定。通常,我见过的每一个类提供它自己的特性结合,在这种情况下,你可以修改代码为:

you'll use First and not _first for the binding. Normally I've seen each class provide it's own properties to bind to, in which case you could modify your code to:

class One : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }

    int _first = 1;
    int _second = 2;
    public int First { get { return _first; }
                       set { _first = value; OnPropertyChanged("First"); } }
    public int Second { get { return _second; }
                        set { _second = value; OnPropertyChanged("Second"); } }
}

class Two : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }

    string _third = "Third";
    string _fourth = "Fourth";
    public string Third { get { return _third; }
                          set { _third = value; OnPropertyChanged("Third"); } }
    public string Fourth { get { return _fourth; }
                           set { _fourth = value; OnPropertyChanged("Fourth"); } }
}

class Comp : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }

    int _int1 = 100;
    One _part1 = new One();
    Two _part2 = new Two();

    public One Part1 { get { return _part1; }
                       set { _part1 = value; OnPropertyChanged("Part1"); } }
    public Two Part2 { get { return _part2; }
                       set { _part2 = value; OnPropertyChanged("Part2"); } }

    public int Int1 { get { return _int1; }
                      set { _int1 = value; OnPropertyChanged("Int1"); } }
}

请注意,我把属性公开,同时保持字段默认为私人的。如果您分配一个父控件的DataContext的,以比较的一个实例:

Note that I made the properties public, while keeping the fields defaulted to private. If you assign the DataContext of a parent control to an instance of Comp:

Comp comp = new Comp();
stack.DataContext = comp;



然后,您可以绑定到XAML的作品如下:

You can then bind to the pieces in xaml as follows:

<Window x:Class="TestApp.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestApp"
    Title="Window1" Height="300" Width="300">
    <StackPanel Name="stack">
        <TextBlock Text="{Binding Int1}"/>
        <TextBlock Text="{Binding Part1.First}"/>
        <TextBlock Text="{Binding Part1.Second}"/>
        <TextBlock Text="{Binding Part2.Third}"/>
        <TextBlock Text="{Binding Part2.Fourth}"/>
    </StackPanel>
</Window>



在这里你会看到的StackPanel给出一个比较的DataContext的(因此它的所有儿童还具有的DataContext除非指定另一个),和文本被绑定到它的部件的类

here you'll see the StackPanel is given a Comp as the DataContext (and therefore all of it's children also have that DataContext unless another one is specified), and the text is bound to it's member classes.

编辑:我在制定者也加入以及实现INotifyPropertyChanged的哪个是一个重要组成部分,以数据绑定。有了这个实现,你就可以将数据绑定到多个控件,并查看所有控制数据更新时更新。你需要添加:
使用System.ComponentModel;

I also added in setters as well as implemented INotifyPropertyChanged which is a vital component to databinding. With this implemented, you'll be able to bind your data to multiple controls and see the data update in all controls when updated. You'll need to add: using System.ComponentModel;

这篇关于WPF数据绑定到复合类的模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆