如何绑定私有财产?

发布于 2024-12-07 22:30:51 字数 2889 浏览 0 评论 0 原文

我有一个数据网格,我需要其中的所有内容都具有完全可扩展的大小。我对列标题没有任何问题,它们都可以正确缩放。我的问题是对于单个细胞,它们似乎不尊重它们的结合。

网格高度的绑定似乎可以很好地设置初始值,但是一旦显示网格,如果它绑定的变量发生变化,它就不会改变高度。

我必须子类化 DataGridTextColumn 来添加一些自定义功能。我有一个名为 CreateDataGridColumn 的方法,它返回对 ExtendedDataGridTextColumn 的引用。然后将这些列添加到数据网格中。数据绑定本身工作正常,网格显示所有正确的数据。

下面是一些代码:

    private ExtendedDataGridTextColumn CreateDataGridColumn(EntityBase dataColumn, FormatConditionGroup formatConditionGroup)
    {
        ExtendedDataGridTextColumn newColumn = new ExtendedDataGridTextColumn(dataColumn);
        DataTemplate dataTemplate = new DataTemplate();
        String textBlockName = "Text" + dataColumn.EntityId;
        String columnTag = dataColumn.GetPropertyValue("Tag");

        // Create the TextBlock that will display the cell contents
        FrameworkElementFactory textBlockFNFactory;
        textBlockFNFactory = new FrameworkElementFactory(typeof(TextBlock));

        _gridTextHeightPercentage = dataColumn.GetPropertyDouble("GridFontSize", Constants.DefaultFontHeightPercent) / 2.8;
        _fontSize = GlobalVariables.DesignerPreviewHeight * (_gridTextHeightPercentage / 100);

        Binding binding = new Binding();
        binding.Source = _fontSize;
        textBlockFNFactory.SetBinding(TextBlock.FontSizeProperty, binding);

        // Do a whole bunch of stuff here

        // Create a border so that the label background does not obscure the grid lines
        FrameworkElementFactory borderFNFactory;
        borderFNFactory = new FrameworkElementFactory(typeof(Border));
        borderFNFactory.AppendChild(textBlockFNFactory);

        // Add type to data template
        dataTemplate.VisualTree = borderFNFactory;

        newColumn.CellTemplate = dataTemplate;

        return newColumn;
    }

然后,我在数据网格的 SizeChanged 事件上触发了以下方法:

        _customDataGrid.TitleAreaHeight = new GridLength(GlobalVariables.DesignerPreviewHeight * (_titleHeightPercentage / 100));
        _customDataGrid.SetHeaderFontSize(GlobalVariables.DesignerPreviewHeight * (_headerHeightPercentage / 100));
        _fontSize = GlobalVariables.DesignerPreviewHeight * (_gridTextHeightPercentage / 100); 

前两行执行其预期的操作,更改标题区域的高度(这是我添加到数据网格中的内容)并更改标头高度。但 _fontSize 变量的更新不会更改数据网格单元格文本高度。

更新

根据建议,我添加了一个依赖属性。

    public static readonly DependencyProperty GridFontHeightProperty = DependencyProperty.Register("GridFontHeight", typeof(double), typeof(CustomDataGrid));

然后将我的绑定代码更改为此。

        binding = new Binding();
        binding.Path = new PropertyPath("GridFontHeight");
        textBlockFNFactory.SetBinding(TextBlock.FontSizeProperty, binding);

然后在我的尺寸改变后添加了这个。

        SetValue(GridFontHeightProperty, _fontSize);

但这不起作用。在这种情况下,它一开始就没有正确设置字体高度,它只是使用数据网格的默认字体高度。

I have a data grid where I need everything to have a fully scalable size. I have no issue with the column headers, they all scale properly. My issue is for the individual cells, they do not seem to respect their binding.

The binding for grid height seems to set the initial value fine, but once the grid is displayed it does not change the height if the variable it is bound to changes.

I had to subclass DataGridTextColumn to add some custom functionality. I have a method called CreateDataGridColumn that returns a reference to ExtendedDataGridTextColumn. These columns are then added to the data grid. The data binding itself works fine, the grid shows all of the correct data.

Here is some code:

    private ExtendedDataGridTextColumn CreateDataGridColumn(EntityBase dataColumn, FormatConditionGroup formatConditionGroup)
    {
        ExtendedDataGridTextColumn newColumn = new ExtendedDataGridTextColumn(dataColumn);
        DataTemplate dataTemplate = new DataTemplate();
        String textBlockName = "Text" + dataColumn.EntityId;
        String columnTag = dataColumn.GetPropertyValue("Tag");

        // Create the TextBlock that will display the cell contents
        FrameworkElementFactory textBlockFNFactory;
        textBlockFNFactory = new FrameworkElementFactory(typeof(TextBlock));

        _gridTextHeightPercentage = dataColumn.GetPropertyDouble("GridFontSize", Constants.DefaultFontHeightPercent) / 2.8;
        _fontSize = GlobalVariables.DesignerPreviewHeight * (_gridTextHeightPercentage / 100);

        Binding binding = new Binding();
        binding.Source = _fontSize;
        textBlockFNFactory.SetBinding(TextBlock.FontSizeProperty, binding);

        // Do a whole bunch of stuff here

        // Create a border so that the label background does not obscure the grid lines
        FrameworkElementFactory borderFNFactory;
        borderFNFactory = new FrameworkElementFactory(typeof(Border));
        borderFNFactory.AppendChild(textBlockFNFactory);

        // Add type to data template
        dataTemplate.VisualTree = borderFNFactory;

        newColumn.CellTemplate = dataTemplate;

        return newColumn;
    }

Then I have the following method fired on the SizeChanged event for the datagrid:

        _customDataGrid.TitleAreaHeight = new GridLength(GlobalVariables.DesignerPreviewHeight * (_titleHeightPercentage / 100));
        _customDataGrid.SetHeaderFontSize(GlobalVariables.DesignerPreviewHeight * (_headerHeightPercentage / 100));
        _fontSize = GlobalVariables.DesignerPreviewHeight * (_gridTextHeightPercentage / 100); 

The first two lines do what they are supposed to, change the height of the title area which is something I added to my data grids and change the header height. The update of the _fontSize variable though does not change the data grid cell text height.

Updated

As per suggestion I added a dependency property as such.

    public static readonly DependencyProperty GridFontHeightProperty = DependencyProperty.Register("GridFontHeight", typeof(double), typeof(CustomDataGrid));

Then changed my binding code to this.

        binding = new Binding();
        binding.Path = new PropertyPath("GridFontHeight");
        textBlockFNFactory.SetBinding(TextBlock.FontSizeProperty, binding);

Then in my size changed added this.

        SetValue(GridFontHeightProperty, _fontSize);

But it does not work. In this scenario it doesn't set the font height correctly to begin with, it just uses the default font height for the data grid.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

泪眸﹌ 2024-12-14 22:30:51

首先,不,你不能绑定到私有变量。我的猜测是,你的变量 _fontSize 是一个 private double,对吧? (看看我怎么猜?;))
您可以绑定到公共属性或依赖属性,这很适合您的情况。因此,创建一个名为 FontSize 的新依赖属性并绑定到它。

如果由于某种原因您无法使用依赖项属性,您仍然可以使用 INotifyPropertyChanged 应该类似于

public double FontSize
{
    get{return _fontSize;}
    set
    {
        _fontSize = value;
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs("FontSize"));
        }
    }
}

First of all, no you can't bind to a private variable. My guess is, that your variable _fontSize is a private double, right? (See how i have to guess? ;))
You can bind to a public property or to a dependency property, which in your case fits well. So create a new dependency Property called FontSize and bind to that.

If for some reason you can't use a dependency property, you can still bind to normal CLR properties using INotifyPropertyChanged which should look something like

public double FontSize
{
    get{return _fontSize;}
    set
    {
        _fontSize = value;
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs("FontSize"));
        }
    }
}
浅唱々樱花落 2024-12-14 22:30:51

我对此有一些意见...

  1. 您的 ExtendedDataGridTextColumn 是否从 DataGridTextColumn 扩展而来,如果是的话,您为何使用 CellTemplateDataGridTextColumn 具有 ElementStyleEditingElementStyle 来设置由其单元格表示的 TextBlock 和 TextBox 的样式。

  2. 如果您对上面第 1 点中关于 CellTemplate 的决定充满信心,那么请尝试...

     绑定绑定 = new Binding();
      绑定.BindsDirectlyToSource = true;
      绑定.Source = _fontSize;
      textBlockFNFactory.SetBinding(TextBlock.FontSizeProperty, 绑定); 
    

如果这些内容有帮助,请告诉我。

I have couple of inputs on this...

  1. Does your ExtendedDataGridTextColumn extend from DataGridTextColumn if so how come you are using CellTemplate? DataGridTextColumn has ElementStyle and EditingElementStyle to style TextBlock and TextBox represented by its cell.

  2. If you are confident of your decision about CellTemplate in point 1 above then try....

      Binding binding = new Binding();
      binding.BindsDirectlyToSource = true;
      binding.Source = _fontSize;
      textBlockFNFactory.SetBinding(TextBlock.FontSizeProperty, binding); 
    

Let me know if any of these help.

路弥 2024-12-14 22:30:51

你没有正确绑定,也不能做(严格来说)你想做的事。

绑定总是针对普通代码属性或依赖属性。您无法绑定到字段。您可以执行以下操作:

首先,删除 _fontSize 实例变量。你不会再使用这个了。

接下来,为此值定义一个 DependencyProperty

    private const string FontSizePropertyName = "FontSize";
    private static readonly DependencyProperty FontSizeProperty = 
    DependencyProperty.Register(
        FontSizePropertyName,
        typeof(double),
        typeof(ExtendedDataGridTextColumn),
        new UIPropertyMetadata(0));
    private double FontSize
    {
        get { return (double)GetValue(FontSizeProperty); }
        set { SetValue(FontSizeProperty, value); }
    }

然后将您的绑定更改为此:

    Binding binding = new Binding();
    binding.Source = RelativeSource.Self;
    binding.Path = new PropertyPath(FontSizeProperty)
    textBlockFNFactory.SetBinding(TextBlock.FontSizeProperty, binding);

然后只需使用新的 FontSize 属性来设置该值,而不是更新私有字段。

注意:您已经接近现有的依赖属性,但如果该属性是 CLR(普通)属性,则 PropertyPath 仅采用 string。对于依赖属性,您应该将实际的 DependencyProperty 实例传递给它,如上所示。

You're not binding correctly, nor can you do (strictly speaking) what you want.

Bindings are always against either ordinary code properties or against dependency properties. You cannot bind to fields. You could do something like this:

First, remove the _fontSize instance variable. You won't be using this anymore.

Next, define a DependencyProperty for this value:

    private const string FontSizePropertyName = "FontSize";
    private static readonly DependencyProperty FontSizeProperty = 
    DependencyProperty.Register(
        FontSizePropertyName,
        typeof(double),
        typeof(ExtendedDataGridTextColumn),
        new UIPropertyMetadata(0));
    private double FontSize
    {
        get { return (double)GetValue(FontSizeProperty); }
        set { SetValue(FontSizeProperty, value); }
    }

Then change your binding to this:

    Binding binding = new Binding();
    binding.Source = RelativeSource.Self;
    binding.Path = new PropertyPath(FontSizeProperty)
    textBlockFNFactory.SetBinding(TextBlock.FontSizeProperty, binding);

Then just use your new FontSize property to set the value rather than updating a private field.

Note: You were close with your existing dependency property, but PropertyPath only takes a string if the property is a CLR (ordinary) property. For dependency properties, you should pass the actual DependencyProperty instance into it as shown above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文