如何计算XAML中定义的XMLDataProvider-data的平均值

时间:2013-03-04 15:26:32

标签: c# xaml data-binding xpath xmldatasource

我是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中对它们执行某些操作?谢谢。

1 个答案:

答案 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 工具