我正在使用Powershell和XAML构建WPF UI。我遇到问题的特殊功能是在列上设置样式。我能够在XAML中设置样式,但是有9列(3个数据网格中各有3列),所以我觉得在代码中设置属性而不是重复相同的块9次会更简洁。
这是我通过XAML在单个列上设置样式的方法:
<DataGridTextColumn Header="Attribute" Binding="{Binding Attribute}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="Text" Value="">
<Setter Property="Background" Value="LightGreen"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
这会将空白单元格设置为浅绿色。但是,我首选的方法是在Powershell中设置它。
到目前为止,我已经找到了如何在Powershell中手动创建列,如果它们没有在XAML中明确添加的话。我这样做(在绑定到控件之后):
$arrAllDataGrids = @($dataGridUser, $dataGridHome, $dataGridWWID)
ForEach ($objDataGrid in $arrAllDataGrids)
{
$objDataGrid.AutoGenerateColumns = $false
$colAttribute = New-Object System.Windows.Controls.DataGridTextColumn -Property @{"Header" = "Attribute"; "Binding" = New-Object System.Windows.Data.Binding "Attribute"}
$colValue = New-Object System.Windows.Controls.DataGridTextColumn -Property @{"Header" = "Value"; "Binding" = New-Object System.Windows.Data.Binding "Value"}
$colDate = New-Object System.Windows.Controls.DataGridTextColumn -Property @{"Header" = "Date"; "Binding" = New-Object System.Windows.Data.Binding "Date"}
$arrColumns = @($colAttribute, $colValue, $colDate)
ForEach ($objColumn in $arrColumns) {$objDataGrid.Columns.Add($objColumn)}
}
但是,如果我尝试通过Powershell添加样式,我会遇到依赖属性。我试图通过在XAML中创建样式然后尝试在Powershell中对其进行逆向工程来检查它们,这是我到目前为止所做的:
$ dataGridUser.Columns [0] .ElementStyle是Type System.Windows.Style $ dataGridUser.Columns [0] .ElementStyle.Triggers是Type System.Windows.Trigger $ dataGridUser.Columns [0] .ElementStyle.Triggers.Property是Type Selected.System.Windows.Trigger $ dataGridUser.Columns [0] .ElementStyle.Triggers.Property.Property是Type System.Windows.DependencyProperty
我无法创建System.Windows.DependencyProperty类型的对象,该对象应该包含Text的Name属性。到目前为止我管理的最好的是通过XAML创建一个列,然后像这样提取Dependency属性对象:
$objDepend = $($dataGridUser.Columns[0].ElementStyle.Triggers | Select Property).Property
使用这个对象,我可以创建一个具有正确触发器属性的新列对象(我很欣赏这仍然缺少'Setter'属性,但我认为相同的原则将适用),如下所示:
$objSelect = $(New-Object System.Windows.Trigger | Select Property)
$objSelect.Property = $objDepend
$objTrigger = New-Object System.Windows.Trigger
$objTrigger.Value = ""
$objTrigger.Property = $objSelect.Property
$objStyle = New-Object System.Windows.Style
$objStyle.Triggers.Add($objTrigger)
$colAttribute = New-Object System.Windows.Controls.DataGridTextColumn -Property @{"Header" = "Attribute"; "Binding" = New-Object System.Windows.Data.Binding "Attribute"; "ElementStyle" = $objStyle}
这显然不是解决这个问题的正确方法,我显然遗漏了一些东西,大概是在Dependency属性周围,我怀疑它是派生的而不是简单的设置。
我希望一切都有意义,任何人都可以帮忙吗?
答案 0 :(得分:1)
我希望回答我自己的(也是唯一的)问题是可以接受的,但我想我会分享我开发的解决方案,以防其他人处于类似的位置。
只需编写一个创建Windows.Style.Object的函数并将其传回。我开始使用两个默认字符串,如下所示:
$strXAMLStart = @"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<DataGrid x:Name="dataGridTrigger">
<DataGrid.Columns>
<DataGridTextColumn>
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>`n
"@
$strXAMLEnd = @"
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
"@
因此,该函数使用传递给它的样式参数简要创建并加载XAML对象,然后提取样式对象并将其作为函数的结果传回。然后,可以将其应用于UI中的列。 功能如下:
Function Set-ColumnStyle ($hashStyle)
{
Add-Type -AssemblyName PresentationFramework
Add-Type -AssemblyName PresentationCore
Add-Type -AssemblyName WindowsBase
Add-Type -AssemblyName System.Windows.Forms
$strXAMLTrigger = $null
ForEach ($key in $hashStyle.Keys)
{
$strValue = $hashStyle[$key]
If ($key -eq "Blank") {$strTrigger = ""}
Else {$strTrigger = $key}
$strXAMLTrigger += " <Trigger Property=`"Text`" Value=`"$strTrigger`">`n"
$strXAMLTrigger += " <Setter Property=`"Background`" Value=`"$strValue`"/>`n"
$strXAMLTrigger += " </Trigger>`n"
}
[xml]$xamlContent = $strXAMLStart + $strXAMLTrigger + $strXAMLEnd
$xamlReader = (New-Object System.Xml.XmlNodeReader $xamlContent)
$xamlWindow = [Windows.Markup.XamlReader]::Load($xamlReader)
$dataGridTrigger = $xamlWindow.FindName("dataGridTrigger")
$objStyle = $dataGridTrigger.Columns[0].ElementStyle
Return $objStyle
}
我使用字符串“blank”来表示实际的空白单元格,因此如果检测到,则将其替换为“”。 您现在可以调用此函数并将列内容的哈希表传递给所需的颜色,并使用返回的对象在列上设置样式:
$hashStyle = @{"Blank" = "#FFFF5050"; "0" = "#FF50FF50"; "267009" = "#FF50FF50"}
$objStyle = Set-ColumnStyle $hashStyle
$colDay = New-Object System.Windows.Controls.DataGridTextColumn -Property @{"Header" = "Day"; "Binding" = New-Object System.Windows.Data.Binding "Day"; "ElementStyle" = $objStyle}
$dataGridScripts.Columns.Add($colDay)
希望一切都有意义!