我是WPF的新手,我需要你的帮助。 我的应用程序允许用户检查大陆和包含国家/地区的视图。国家有两个品牌:名称和面积。问题是我需要显示所有大陆国家的平均面积。 我的数据模型如下所示:
<XmlDataProvider x:Key="CountryStoreDataSource" XPath="CountryStore">
<x:XData>
<CountryStore xmlns="">
<Continents Continent="Europe">
<Countries Country="Italy" Area="300"/>
<Countries Country="Iceland" Area="350"/>
</Continents>
<Continents Continent="Asia">
<Countries Country="China" Area="700"/>
<Countries Country="India" Area="650"/>
</Continents>
<Continents Continent="Africa">
<Countries Country="South Africa" Area="550"/>
<Countries Country="Egypt" Area="500"/>
</Continents>
</CountryStore>
</x:XData>
</XmlDataProvider>
我也有模板将列表框与我的数据模型连接起来:
<Grid.Resources>
<DataTemplate x:Key="countryItemTemplate">
<Label Content="{Binding XPath=@Country}"/>
</DataTemplate>
<DataTemplate x:Key="areaItemTemplate">
<Label Content="{Binding XPath=@Area}"/>
</DataTemplate>
</Grid.Resources>
最后我有我的列表框的实现:
<ListBox
Grid.Row="1"
ItemsSource="{Binding XPath=Countries}"
ItemTemplate="{StaticResource countryItemTemplate}"
Margin="0,0,0,0" />
<ListBox
Grid.Row="1"
ItemsSource="{Binding XPath=Countries}"
ItemTemplate="{StaticResource areaItemTemplate}"
Margin="0,0,0,0"
Grid.Column="1"
Name="listBoxAreas"
/>
实际上我不知道如何从c#代码中的列表框中获取我的值,是否有任何方法可以获取值并在xml中对它们执行某些操作?谢谢。
答案 0 :(得分:1)
有趣的问题!
首先,您使用的XPath似乎并不完全正确。如果我理解正确,您希望显示带有国家/地区的列表框,带有区域的列表框和带有Avg(areas)
的文本块。
首先,让我们简化XPath绑定。您应该更新XmlDataSource上的XPath,这样您就可以获得独立于Continent的国家/地区列表:
<XmlDataProvider x:Key="CountryStoreDataSource" XPath="/CountryStore/Continents/Countries">
<x:XData>
<CountryStore xmlns="">
<Continents Continent="Europe">
<Countries Country="Italy" Area="300"/>
<Countries Country="Iceland" Area="350"/>
</Continents>
<Continents Continent="Asia">
<Countries Country="China" Area="700"/>
<Countries Country="India" Area="650"/>
</Continents>
<Continents Continent="Africa">
<Countries Country="South Africa" Area="550"/>
<Countries Country="Egypt" Area="500"/>
</Continents>
</CountryStore>
</x:XData>
</XmlDataProvider>
然后,设置Grid的DataContext:
<Grid DataContext="{StaticResource CountryStoreDataSource}" ../>
之后,ListBoxes的两个绑定都可以更新为以下内容:ItemsSource="{Binding}"
。
现在,回到问题:显示区域的平均值。为此,您需要绑定到相同的列表并应用转换器来进行计算 首先,让我们创建转换器,它只是解析列表并使用LINQ计算平均值:
public class AreaConverter : MarkupExtension, IValueConverter
{
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return 0;
//you can do this in one line, but I split it for clarity.
var xml = value as IEnumerable<XmlNode>;
var areas = xml.Select(x => x.Attributes["Area"].Value);
var avg = areas.Average(a => int.Parse(a));
return avg;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportException();
}
}
之后,您可以使用此绑定创建TextBlock来保存此值:
<TextBlock Text="{Binding Converter={local:AreaConverter}}" />
现在TextBlock应该显示Average!
提示:要测试您给定的XPath,您可以将Notepad ++与XML Tools插件一起使用,该插件提供 Evaluate XPath Expression 工具