我有一个dataGrid,其中包含使用DataGridTemplateColumn技术创建的列。 这是我在DataGrid(Name =“Dgrv)
中感兴趣的列<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>
在我的后端,我有下一个代码:
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;
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”
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类只是为了理解所需的技术。
答案 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));
}
}
实现编写所有这些样板代码。但是我受到了偏见。
我希望这会/将会有用。