我有一个数据网格,我需要其中的所有内容都具有完全可扩展的大小。我对列标题没有任何问题,它们都可以正确缩放。我的问题是对于单个细胞,它们似乎不尊重它们的结合。
网格高度的绑定似乎可以很好地设置初始值,但是一旦显示网格,如果它绑定的变量发生变化,它就不会改变高度。
我必须子类化 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.
发布评论
评论(3)
首先,不,你不能绑定到私有变量。我的猜测是,你的变量 _fontSize 是一个
private double
,对吧? (看看我怎么猜?;))您可以绑定到公共属性或依赖属性,这很适合您的情况。因此,创建一个名为 FontSize 的新依赖属性并绑定到它。
如果由于某种原因您无法使用依赖项属性,您仍然可以使用 INotifyPropertyChanged 应该类似于
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
我对此有一些意见...
您的
ExtendedDataGridTextColumn
是否从DataGridTextColumn
扩展而来,如果是的话,您为何使用CellTemplate
?DataGridTextColumn
具有ElementStyle
和EditingElementStyle
来设置由其单元格表示的 TextBlock 和 TextBox 的样式。如果您对上面第 1 点中关于
CellTemplate
的决定充满信心,那么请尝试...如果这些内容有帮助,请告诉我。
I have couple of inputs on this...
Does your
ExtendedDataGridTextColumn
extend fromDataGridTextColumn
if so how come you are usingCellTemplate
?DataGridTextColumn
hasElementStyle
andEditingElementStyle
to style TextBlock and TextBox represented by its cell.If you are confident of your decision about
CellTemplate
in point 1 above then try....Let me know if any of these help.
你没有正确绑定,也不能做(严格来说)你想做的事。
绑定总是针对普通代码属性或依赖属性。您无法绑定到字段。您可以执行以下操作:
首先,删除
_fontSize
实例变量。你不会再使用这个了。接下来,为此值定义一个
DependencyProperty
:然后将您的绑定更改为此:
然后只需使用新的
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:Then change your binding to this:
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 astring
if the property is a CLR (ordinary) property. For dependency properties, you should pass the actualDependencyProperty
instance into it as shown above.