【问题标题】:Second-level property binding in wpf Datagrid DataGridTemplateColumn TextBlockwpf Datagrid DataGridTemplateColumn TextBlock中的二级属性绑定
【发布时间】:2016-04-21 23:49:17
【问题描述】:

我有一个 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 类作为示例,以便了解所需的技术。

【问题讨论】:

  • 不应该是{Binding smth.txtbx}吗?
  • 我不明白,这怎么可能,但它确实有效。我已经多次尝试过您的变体,但没有奏效。在您发表评论后,我决定再试一次,它奏效了。非常感谢。请告诉我,如何将答案标记为正确答案?
  • 我发布了一个答案,试图尽我所能解释事情。您应该能够将其标记为答案。谢谢。

标签: c# wpf templates binding datagrid


【解决方案1】:

答案很简单。

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

当你写{Binding TextCell.txtbx} 时,它当然不会工作,因为你在Contract 上没有一个名为TextCell 的属性。您有一个名为 smthTextCell 类型的属性。同样,在 C# 代码中,您将尝试使用以下代码访问该属性:

var list = new List(); list.Add(新合同 { ID = 1, CompanyName = "Технабсервис", HeadName = "Петров\nАлександр\nНиколаевич", 国家代码 = "+7", 操作员代码 = "495", Date = Convert.ToDateTime("21.02.2012").ToString("dd.MM"), //GetDateTimeFormats('mm, dd'), 时间 = "16:39", 电话 = "(495)123-4567 (общий)", 评论 = "" }); var x = list[0].smth.txtbx;

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

您可以阅读有关Binding 标记扩展here 的语法的更多信息。

您的代码仍有一些问题。如果您从代码中更新字段,则不会更新 UI。为了使list[0].smth.txtbx = "Updated Text"; 工作,您应该在ContractTextCell 类上实现INotifyPropertyChanged 接口。大致如下:

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 类:

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));
    }
}

我知道这是很多样板代码,但不幸的是,如果您希望您的绑定收到来自视图模型/模型的更改的通知,则需要此代码。 有一个非常好的库,叫做PropertyChanged for Fody,它可以让你避免为INotifyPropertyChanged 实现编写所有这些样板代码。但我走偏了。

我希望这是/将是有用的。

【讨论】:

  • 我很抱歉消失了,项目已经关闭,但是这个答案仍然有用,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-12
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 2010-10-14
相关资源
最近更新 更多