如何在 WPF MVVM 方法中将 DataGrid 的数字列右对齐?
How do I allign numeric columns of a DataGrid to the right in WPF MVVM approach?
我正在使用像这样的 MVVM 方法将 ViewModel
中的动态集合绑定到 datagrid
:
var Data = (
from main in db.MainSaleInvoiceTbls
join detial in db.DetialSaleInvoiceTbls
on main.Id equals detial.MainSaleInvoiceId into gDate
from gdetial in gDate.DefaultIfEmpty()
where main.IsActive == true
&& main.CompanyId == UniversalInfo.UserCompany.Id
&& main.MainSaleInvoiceDataType == MainSaleInvoiceType.POInvoice
&& main.FinancialYearId == UniversalInfo.SelectedFinancialYear.Id
orderby main.Id
select
new
{
Id=main.Id,
Sr_No=0,
Date = main.Date.Value,
Voucher = main.FinancialVoucher,
Invoice_Account = main.Vendor == null ? string.Empty : main.Vendor.AccountCode,
Vendor_Name = main.Vendor == null ? string.Empty : main.Vendor.VendorName,
Vendor_Group = main.Vendor == null ? string.Empty : main.Vendor.VendorGroup.Name,
Invoice = main.SaleOrderPrefix + main.SaleOrderNumber,
Purchase_Order = main.SalesId,
Sales_Tax = "",
Invoice_Amount= gDate.Sum(x=>x.Quantity * x.UnitPrice)
});
DataGridCollection = new ObservableCollection<dynamic>(data);
XML 数据绑定到网格的代码是:
<DataGrid x:Name="miscListDataGrid"
VerticalAlignment="Stretch"
ScrollViewer.IsDeferredScrollingEnabled="True"
VirtualizingPanel.IsContainerVirtualizable="True"
VirtualizingPanel.IsVirtualizing="True"
EnableRowVirtualization="True"
EnableColumnVirtualization="True"
ItemsSource="{Binding Path=DataGridCollection,IsAsync=True,Mode=TwoWay,NotifyOnTargetUpdated=True,NotifyOnSourceUpdated=True,ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged,ValidatesOnExceptions=True}"
AutoGenerateColumns="True"
Grid.Row="2"
RowDetailsVisibilityMode="VisibleWhenSelected"
Grid.ColumnSpan="2"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
IsReadOnly="True"
>
</DataGrid>
我的要求是如何将数字列对齐到右侧?
我尝试使用 AutoGeneratingColumn
和 RowDetailsVisibilityChanged
事件来查明 DataGrid 何时初始化其列并触发这些事件。 AutoGeneratingColumn
当列第一次填充到网格中时触发。它不允许将 CellStyle
或 Alignment
更改为右侧。
如果有人能阐明事件如何触发以格式化列,那将非常有帮助。
感谢您的宝贵时间。
当DataGrid.AutogenerateColumns
设置为True
时应使用以下代码。
在 XAML 中手动创建列时,您只需指定 DataGridBoundColumn.ElementStyle
.
在这两种情况下,Style
必须以 TextBlock
为目标。这是因为默认情况下,框架将生成一个 TextBlock
作为单元格内容宿主(或一个 CheckBox
作为布尔值)。
DataGridTextColumn
的单元格对齐是通过 DataGridTextColumn.ElementStyle
设置单元格内容宿主的 TextBlock.TextAlignment
属性 来实现的。
MainWindow.xaml
<Window>
<Window.Resources>
<Style x:Key="NumericDataGridCellStyle" TargetType="TextBlock">
<Setter Property="TextAlignment" Value="Right" />
</Style>
</Window.Resources>
<DataGrid AutoGenerateColumns="True"
AutoGeneratingColumn="DataGrid_OnAutoGeneratingColumn" />
</Window>
MainWindow.xaml.cs
partial class MainWindow
{
private void DataGrid_OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (!(e.Column is DataGridTextColumn textColumn))
{
return;
}
var columnIsNumeric = e.PropertyType == typeof(decimal)
|| e.PropertyType == typeof(int)
|| e.PropertyType == typeof(double);
if (columnIsNumeric)
{
var numericCellStyle = FindResource("NumericDataGridCellStyle") as Style;
textColumn.ElementStyle = numericCellStyle;
}
}
}
我正在使用像这样的 MVVM 方法将 ViewModel
中的动态集合绑定到 datagrid
:
var Data = (
from main in db.MainSaleInvoiceTbls
join detial in db.DetialSaleInvoiceTbls
on main.Id equals detial.MainSaleInvoiceId into gDate
from gdetial in gDate.DefaultIfEmpty()
where main.IsActive == true
&& main.CompanyId == UniversalInfo.UserCompany.Id
&& main.MainSaleInvoiceDataType == MainSaleInvoiceType.POInvoice
&& main.FinancialYearId == UniversalInfo.SelectedFinancialYear.Id
orderby main.Id
select
new
{
Id=main.Id,
Sr_No=0,
Date = main.Date.Value,
Voucher = main.FinancialVoucher,
Invoice_Account = main.Vendor == null ? string.Empty : main.Vendor.AccountCode,
Vendor_Name = main.Vendor == null ? string.Empty : main.Vendor.VendorName,
Vendor_Group = main.Vendor == null ? string.Empty : main.Vendor.VendorGroup.Name,
Invoice = main.SaleOrderPrefix + main.SaleOrderNumber,
Purchase_Order = main.SalesId,
Sales_Tax = "",
Invoice_Amount= gDate.Sum(x=>x.Quantity * x.UnitPrice)
});
DataGridCollection = new ObservableCollection<dynamic>(data);
XML 数据绑定到网格的代码是:
<DataGrid x:Name="miscListDataGrid"
VerticalAlignment="Stretch"
ScrollViewer.IsDeferredScrollingEnabled="True"
VirtualizingPanel.IsContainerVirtualizable="True"
VirtualizingPanel.IsVirtualizing="True"
EnableRowVirtualization="True"
EnableColumnVirtualization="True"
ItemsSource="{Binding Path=DataGridCollection,IsAsync=True,Mode=TwoWay,NotifyOnTargetUpdated=True,NotifyOnSourceUpdated=True,ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged,ValidatesOnExceptions=True}"
AutoGenerateColumns="True"
Grid.Row="2"
RowDetailsVisibilityMode="VisibleWhenSelected"
Grid.ColumnSpan="2"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
IsReadOnly="True"
>
</DataGrid>
我的要求是如何将数字列对齐到右侧?
我尝试使用 AutoGeneratingColumn
和 RowDetailsVisibilityChanged
事件来查明 DataGrid 何时初始化其列并触发这些事件。 AutoGeneratingColumn
当列第一次填充到网格中时触发。它不允许将 CellStyle
或 Alignment
更改为右侧。
如果有人能阐明事件如何触发以格式化列,那将非常有帮助。
感谢您的宝贵时间。
当DataGrid.AutogenerateColumns
设置为True
时应使用以下代码。
在 XAML 中手动创建列时,您只需指定 DataGridBoundColumn.ElementStyle
.
在这两种情况下,Style
必须以 TextBlock
为目标。这是因为默认情况下,框架将生成一个 TextBlock
作为单元格内容宿主(或一个 CheckBox
作为布尔值)。
DataGridTextColumn
的单元格对齐是通过 DataGridTextColumn.ElementStyle
设置单元格内容宿主的 TextBlock.TextAlignment
属性 来实现的。
MainWindow.xaml
<Window>
<Window.Resources>
<Style x:Key="NumericDataGridCellStyle" TargetType="TextBlock">
<Setter Property="TextAlignment" Value="Right" />
</Style>
</Window.Resources>
<DataGrid AutoGenerateColumns="True"
AutoGeneratingColumn="DataGrid_OnAutoGeneratingColumn" />
</Window>
MainWindow.xaml.cs
partial class MainWindow
{
private void DataGrid_OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (!(e.Column is DataGridTextColumn textColumn))
{
return;
}
var columnIsNumeric = e.PropertyType == typeof(decimal)
|| e.PropertyType == typeof(int)
|| e.PropertyType == typeof(double);
if (columnIsNumeric)
{
var numericCellStyle = FindResource("NumericDataGridCellStyle") as Style;
textColumn.ElementStyle = numericCellStyle;
}
}
}