2013-03-04 1 views
2

Je suis vraiment nouveau dans WPF et j'ai besoin de votre aide. J'ai l'application qui permet à l'utilisateur de vérifier le continent et de voir les pays contenant. Le pays a deux propriétés: nom et région. Le problème est que je dois montrer la superficie moyenne de tous les pays du continent. Mon modèle de données est ressemble à ceci:Comment calculer la moyenne de XMLDataProvider-données définies dans XAML

 <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> 

aussi j'ai des modèles pour se connecter listboxes avec mon modèle de données:

 <Grid.Resources> 
      <DataTemplate x:Key="countryItemTemplate"> 
       <Label Content="{Binding [email protected]}"/> 
      </DataTemplate> 
      <DataTemplate x:Key="areaItemTemplate"> 
       <Label Content="{Binding [email protected]}"/> 
      </DataTemplate> 
     </Grid.Resources> 

enfin j'ai les implémentations de mes listboxes:

  <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" 
       /> 

En fait, je ne sais pas comment obtenir mes valeurs à partir de listboxes dans le code C# et y at-il un moyen d'obtenir des valeurs et de faire quelque chose avec eux en XML? Je vous remercie.

Répondre

1

question intéressante! Tout d'abord, il semble que les XPaths que vous utilisez ne sont pas tout à fait corrects. Si je vous comprends bien, vous voulez afficher un ListBox avec des pays, un ListBox avec des zones et un TextBlock avec Avg(areas). En premier lieu, simplifions la liaison XPath. Vous devez mettre à jour le XPath sur votre XmlDataSource afin que vous venez d'obtenir une liste des pays, indépendamment du 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> 

Ensuite, définissez le DataContext de la grille:

<Grid DataContext="{StaticResource CountryStoreDataSource}" ../> 

Après cela, les deux liaisons ListBoxes peut être mis à jour comme suit: ItemsSource="{Binding}".


Maintenant, retour à la question: montrez la moyenne des zones. Pour cela, vous devez vous lier à la même liste et appliquer un convertisseur pour effectuer le calcul.
Tout d'abord, nous allons créer le convertisseur, qui parse simplement la liste et calcule la moyenne avec 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(); 
    } 
} 

Après cela, vous pouvez créer le TextBlock pour maintenir cette valeur avec cette liaison:

<TextBlock Text="{Binding Converter={local:AreaConverter}}" /> 

Maintenant, le TextBlock devrait afficher la moyenne!

TIP: pour tester vos données XPath, vous pouvez utiliser Notepad ++ avec le plugin Outils XML qui fournit une Évaluer Expression XPath outil

+0

merci beaucoup, comment puis-je ajouter correctement ma classe AreaConverter dans mon fichier xml? il ne reconnaît pas {local: AreaConverter} – aparesidam

+0

vous devez définir l'espace de noms à la racine de votre xaml: '' – RoelF