Reputation: 2949
I need to be able to use a series of attributes as the source in a WPF list view. I'm currently stuck on how to do this. I know how to do it for XML nodes but not for attributes. Here's an example of what I'm trying to bind too:
<Stats HP="55000" MP="2500" SP="2500" Strength="212" Vitality="125" Magic="200" Spirit="162" Skill="111" Speed="109" Evasion="100" MgEvasion="100" Accuracy="100" Luck="55" />
I want each stat name/value to be an entry in the listview. Here's the code I've been trying to make work:
<TabControl.DataContext>
<Binding ElementName="EnemyLevelsListBox" Path="SelectedItem"/>
</TabControl.DataContext>
<TabItem Header="Stats" Name="EnemyStatsTab">
<ListView ItemsSource="{Binding XPath=Stats}" Height="310" Name="EnemyStatViewDisplay" Width="411" HorizontalAlignment="Left">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Attribute.Name}" />
<TextBlock Text="{Binding Path=Attribute.Value}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</TabItem>
The TabControl.DataContext binding exposes the parent XMLNode of the Stats element. I know this for certain as I'm using subnodes of the parent elsewhere and they work correctly. I don't know what to put for the ListView ItemsSource or for the DataTemplate's textblock binds. Does someone know how to do this?
Upvotes: 0
Views: 1898
Reputation: 9677
Why not just bind the listview to the attributes?
XAML:
<Window x:Class="WPF1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF1"
Title="MainWindow" Height="350" Width="350">
<StackPanel>
<StackPanel.Resources>
<local:AttributesToEnumerableConverter x:Key="AttributesToEnumerableConverter" />
</StackPanel.Resources>
<ListView ItemsSource="{Binding Path=Stats, Converter={StaticResource AttributesToEnumerableConverter}}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" Margin="5" />
<TextBlock Text="{Binding Path=Value}" Margin="5" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Window>
Code behind:
using System;
using System.Windows;
using System.Windows.Data;
using System.Xml.Linq;
namespace WPF1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
public XElement Stats
{
get { return XElement.Parse("<Stats HP=\"55000\" MP=\"2500\" SP=\"2500\" Strength=\"212\" Vitality=\"125\" Magic=\"200\" Spirit=\"162\" Skill=\"111\" Speed=\"109\" Evasion=\"100\" MgEvasion=\"100\" Accuracy=\"100\" Luck=\"55\" />"); }
}
}
public class AttributesToEnumerableConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (value as XElement).Attributes();
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
Upvotes: 1
Reputation: 184526
You should not use XPath
in the ItemsSource
binding as you want to target the Attributes
collection on the XmlNode
object. You should make sure you are already having the Stats
element as DataContext
, then set the Path
to Attributes
:
<ListView ItemsSource="{Binding Attributes}" DataContext="<bind to stats element if necessary>">
<ListView.View>
<GridView>
<GridViewColumn Header="Stat" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Header="Value" DisplayMemberBinding="{Binding Value}"/>
</GridView>
</ListView.View>
</ListView>
Upvotes: 1