我有一个PowerShell数组,如果我导出为XML,它将如下所示:
<?xml version="1.0"?>
<Objects>
<Object>
<Property Name="Server">Server1</Property>
<Property Name="Issue">hard drive 0 failed</Property>
</Object>
</Objects>
我想让这个数组在GUI中显示。在谷歌搜索之后,我发现可以使用WPF来达到这个目标,但我从来没有使用过它,所以我很难解决这个问题:
经过另一天的谷歌搜索后,我发现DataGrid更适合我的情况,因为根据传递的ItemsSource对象自动生成列数。
现在我遇到了一个新问题,这是我的代码:
$btn = New-Object System.Windows.Controls.Button
$dt = New-Object System.Windows.DataTemplate
$dt.VisualTree = New-Object System.Windows.FrameworkElementFactory($btn)
$dgtc = New-Object System.Windows.Controls.DataGridTemplateColumn
$dgtc.CellTemplate = $dt
$faults = Get-UcsFault -Severity critical | select @{n=’Server’; e={$_.Dn}},
@{n=’Issue’;e={$_.Issue}},
@{n=’Create Ticket’;e={[System.Windows.Controls.DataGridTemplateColumn]$dgtc}}
$result = New-Object System.Windows.Window -prop @{
Content = New-Object System.Windows.Controls.DataGrid -prop @{ItemsSource=$faults};}
$result.ShowDialog()
但是我没有在实际按钮中看到最后一栏中的类名(即System.Windows.Controls.Button)
答案 0 :(得分:0)
听起来你想根据XML对象创建一个类。
public class yourObject //Whatever you want to call it.
{
public string Server {get;set;}
public string Issue {get;set;}
//ETC
}
完成类设置后,Id会浏览XML文件并将数据放入列表中。
string filepath = Directory.GetParent(Environment.CurrentDirectory).Parent.FullName + @"\OBJECTS.xml";
//Path to XML file
List<yourObject> list = new List<yourObject>();
var maps = from c in XElement.Load(filepath).Elements("Object")
select c;
foreach (var item in maps)
{
var newObject= new yourObject();
//Names of your nodes
newObject.Server= item.Element("Server").Value;
newObject.Issue= item.Element("Issue").Value;
list.Add(newObject);
}
//Probably a good idea to make it an observable collection.
objectList= new ObservableCollection<youtObject>();
foreach (var item in list)
{
objectList.Add(item);
}
一旦它在列表中,并且您不想绑定它,您只需将Datagrid的Item源或listview设置为该列表
答案 1 :(得分:0)
public partial class MainWindow : Window
{
private ObservableCollection<ServerIssue> serverIssues;
public MainWindow()
{
// Linq to XML for elegant Selections
XElement doc = XElement.Load("serverissues.xml");
var xmlServerIssues = from objectElt in doc.Descendants("Object")
let propertiesElts = objectElt.Elements("Property")
let serverElt = propertiesElts.FirstOrDefault(elt => elt.Attribute("Name").Value == "Server")
let issueElt = propertiesElts.FirstOrDefault(elt => elt.Attribute("Name").Value == "Issue")
select new ServerIssue {
Server = ((serverElt.FirstNode) as XText).Value,
Issue = ((issueElt.FirstNode) as XText).Value
};
// store enumerated data in ObservableCollection<>
// List<> would be fine but is less agile when adding/removing elements
serverIssues = new ObservableCollection<ServerIssue>(xmlServerIssues);
InitializeComponent();
// Provide data to graphical Grid
datagridIssues.ItemsSource = serverIssues;
}
private void SendToJIRA(object sender, RoutedEventArgs e)
{
// ...
}
}
<Window x:Class="XmlToDataGrid.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid x:Name="datagridIssues" CanUserAddRows="False" CanUserDeleteRows="False" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Server}" IsReadOnly="true"/>
<DataGridTextColumn Binding="{Binding Issue}" IsReadOnly="true"/>
<DataGridTemplateColumn >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Send to JIRA" Click="SendToJIRA" Margin="10 4" Padding="5 3"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
修改强>
这是PowerShell中的翻译。即使在C#中,它也不那么明显。 我真的很鼓励你用C#编写这样的代码。您将拥有一个编译器,一个严肃的调试器。
[reflection.assembly]::loadwithpartialname("PresentationFramework") | Out-Null
# $faults = Get-UcsFault -Severity critical | select @{n=’Server’; e={$_.Dn}},
# @{n=’Issue’;e={$_.Issue}},
# @{n=’Create Ticket’;e={$bt}}
######################################################################################
$serverIssue1 = New-Object psobject -Property @{
Server="server1"
Issue="issue1"
}
$serverIssue2 = New-Object psobject -Property @{
Server="server2"
Issue="issue2"
}
$serverIssues = New-Object System.Collections.Generic.List``1[Object]
$serverIssues.Add( $serverIssue1 )
$serverIssues.Add( $serverIssue2 )
$datagrid = New-Object Windows.Controls.DataGrid -prop @{
AutoGenerateColumns=$FALSE; ItemsSource = $serverIssues;
CanUserAddRows=$FALSE
CanUserDeleteRows=$FALSE
}
#$datagrid.ItemsSource=$faults
# create the binding for a column
$bindingIssue = New-Object System.Windows.Data.Binding -prop @{ Path='Issue'}
# create the column
$columnIssue = New-Object System.Windows.Controls.DataGridTextColumn -prop @{ IsReadOnly=$TRUE;Binding=$bindingIssue}
$datagrid.Columns.Add($columnIssue)
# create the binding for a column
$bindingServer = New-Object System.Windows.Data.Binding -prop @{ Path='Server'}
# create the column
$columnServer = New-Object System.Windows.Controls.DataGridTextColumn -prop @{ IsReadOnly=$TRUE;Binding=$bindingServer}
$datagrid.Columns.Add($columnServer)
# create 3rd column : it s a template, more complicated ! Real WPF hardcore stuff
# not easy in C#, hard tests in PS !
$factory = New-Object System.Windows.FrameworkElementFactory([System.Windows.Controls.Button])
$factory.SetValue( [System.Windows.Controls.Button]::ContentProperty, "Send to Jira")
$thickness = New-Object System.Windows.Thickness(10,5,10,5)
$factory.SetValue( [System.Windows.Controls.Button]::PaddingProperty, $thickness )
$factory.SetValue( [System.Windows.Controls.Button]::MarginProperty, $thickness )
# let's plug a callback when the button is clicked
$factory.AddHandler([System.Windows.Controls.Button]::ClickEvent, [System.Windows.RoutedEventHandler]{
PARAM ([Object]$sender, [Windows.RoutedEventArgs]$e)
# replace with code that sends to Jira
# the DataContext is for the current line of DataGrid. It 's inherited by every component of the line
# so the button has a serverIssue DataContext
$serverIssue = $sender.DataContext
[System.Windows.MessageBox]::Show($serverIssue.Server);
})
$dataTemplate = New-Object System.Windows.DataTemplate -prop @{ VisualTree = $factory }
$columnButton = New-Object System.Windows.Controls.DataGridTemplateColumn -prop @{ IsReadOnly = $TRUE; CellTemplate = $dataTemplate }
$datagrid.Columns.Add($columnButton)
$result = New-Object System.Windows.Window -prop @{ Content = $datagrid }
$result.ShowDialog()
此致