wpf Datagrid DataGridTemplateColumn TextBlock中的第二级属性绑定

时间:2016-01-16 12:43:08

标签: c# wpf templates binding datagrid

我有一个dataGrid,其中包含使用DataGridTemplateColumn技术创建的列。 这是我在DataGrid(Name =“Dgrv)

中感兴趣的列

XAML

<DataGridTemplateColumn Width="40">
                    <!--="Name"-->
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <TextBlock Text="{Binding TextCell.txtbx}" 
                                           TextAlignment="Center" Margin="0, 8, 0, 0"/>
                                <Canvas Background="Black" Height="1" Margin="5,5,5,0"/>
                                <TextBlock Text="{Binding OperatorCode}" TextAlignment="Center" Margin="0, 5, 0, 0"/>
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

在我的后端,我有下一个代码:

XAML.cs

var list = new List<Contract>();
        list.Add(new Contract
        {
            ID = 1,
            CompanyName = "Технабсервис",
            HeadName = "Петров\nАлександр\nНиколаевич",
            CountryCode = "+7",
            OperatorCode = "495",
            Date = Convert.ToDateTime("21.02.2012").ToString("dd.MM"), //GetDateTimeFormats('mm, dd'), 
            Time = "16:39",
            Telephones = "(495)123-4567 (общий)",
            Comment = ""
        });
Dgrv.ItemsSource = list;

这是我的班级Contract.cs

public class Contract
    {
        public int ID { get; set; }
        public string CompanyName { get; set; }
        public string HeadName { get; set; }
        public string CountryCode { get; set; }
        public string OperatorCode { get; set; }
        public String Date { get; set; }
        public String Time { get; set; }
        public String Telephones { get; set; }
        public String Comment { get; set; }
        public TextCell smth { get; set; }

        /*public Dictionary<string, int> PriceFields { get; private set; }
        public Dictionary<string, string> RateFields { get; private set; }
        public Dictionary<string, string> TypeFields { get; private set; }
        public Dictionary<string, string> TicketFields { get; private set; }*/

        public Contract()
        {
            smth = new TextCell();
        }
    }

最后我的类TextCell(你可以看到,我想将TextBlock的文本绑定到这个类的字段,名称为“txtbx”

TextCell.cs

public class TextCell
    {
        public String txtbx { get; set; }
        public TextCell()
        {
            txtbx = "sdbjshfk";
        }

        public override string ToString()
        {
            return txtbx;
        }
    }

所以,问题是这部分代码

<TextBlock Text="{Binding TextCell.txtbx}" 
                                               TextAlignment="Center" Margin="0, 8, 0, 0"/>

根本不起作用。我明白,我可以将TextBlock的文本绑定到TextCell字段本身。在这种情况下将调用ToString()方法,但这对我来说还不够。主要是因为这篇文章中描述的情况仅仅是一个例子,我有更多的情况需要这种类型的绑定。

因此,创建TextCell类只是为了理解所需的技术。

1 个答案:

答案 0 :(得分:1)

答案很简单。

如果要绑定到子属性,则必须使用Binding标记扩展名中的属性名称。

当您撰写{Binding TextCell.txtbx}时,它当然无法运作,因为您在TextCell上没有名为Contract的媒体资源。您有一个名为TextCell的{​​{1}}类型的属性。与C#代码类似,您将尝试使用以下代码访问该属性:

var list = new List();
list.Add(new Contract
{
    ID = 1,
    CompanyName = "Технабсервис",
    HeadName = "Петров\nАлександр\nНиколаевич",
    CountryCode = "+7",
    OperatorCode = "495",
    Date = Convert.ToDateTime("21.02.2012").ToString("dd.MM"), //GetDateTimeFormats('mm, dd'), 
    Time = "16:39",
    Telephones = "(495)123-4567 (общий)",
    Comment = ""
});

var x = list[0].smth.txtbx;

顺便说一句,您应该与您的命名约定保持一致。您应该将Pascal casing用于公共属性。

您可以详细了解smth标记扩展程序here的语法。

您的代码仍有问题。如果您对代码中的字段进行更新,则无法更新UI。为了使Binding有效,您应该在list[0].smth.txtbx = "Updated Text";INotifyPropertyChanged类上实施Contract界面。这些方面的东西:

TextCell

对于public class Contract : INotifyPropertyChanged { private int _id; private string _companyName; private string _headName; private string _countryCode; private string _operatorCode; private string _date; private string _time; private string _telephones; private string _comment; private TextCell _smth; public int ID { get { return _id; } set { _id = value; OnPropertyChanged(); } } public string CompanyName { get { return _companyName; } set { _companyName = value; OnPropertyChanged(); } } public string HeadName { get { return _headName; } set { _headName = value; OnPropertyChanged(); } } public string CountryCode { get { return _countryCode; } set { _countryCode = value; OnPropertyChanged(); } } public string OperatorCode { get { return _operatorCode; } set { _operatorCode = value; OnPropertyChanged(); } } public String Date { get { return _date; } set { _date = value; OnPropertyChanged(); } } public String Time { get { return _time; } set { _time = value; OnPropertyChanged(); } } public String Telephones { get { return _telephones; } set { _telephones = value; OnPropertyChanged(); } } public String Comment { get { return _comment; } set { _comment = value; OnPropertyChanged(); } } public TextCell smth { get { return _smth; } set { _smth = value; OnPropertyChanged(); } } /*public Dictionary<string, int> PriceFields { get; private set; } public Dictionary<string, string> RateFields { get; private set; } public Dictionary<string, string> TypeFields { get; private set; } public Dictionary<string, string> TicketFields { get; private set; }*/ public Contract() { smth = new TextCell(); } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { var handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } } 类:

TextCell

我知道这是很多样板代码,但遗憾的是,如果您希望通知视图模型/模型发生更改,您需要这样做。 有一个非常好的库PropertyChanged for Fody,可以避免为public class TextCell : INotifyPropertyChanged { private string _txtbx; public String txtbx { get { return _txtbx; } set { _txtbx = value; OnPropertyChanged(); } } public TextCell() { txtbx = "sdbjshfk"; } public override string ToString() { return txtbx; } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { var handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } } 实现编写所有这些样板代码。但是我受到了偏见。

我希望这会/将会有用。