2

私は WPF の初心者で、あなたの助けが必要です。ユーザーが大陸をチェックし、含まれる国を表示できるアプリがあります。Country には name と area の 2 つのプロパティがあります。問題は、すべての大陸の国の平均面積を表示する必要があることです。私のデータモデルは次のようになります。

       <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で何かを行う方法はありますか? ありがとうございました。

4

1 に答える 1

1

面白い質問です!

まず第一に、使用しているXPathが完全に正しくないようです。私があなたを正しく理解しているなら、あなたは国を含むリストボックス、領域を含むリストボックス、そして。を含むテキストブロックを表示したいと思いますAvg(areas)

まず、XPathバインディングを単純化しましょう。XmlDataSourceのXPathを更新して、大陸に関係なく国のリストを取得できるようにする必要があります。

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

次に、グリッドのDataContextを設定します。

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

その後、リストボックスの両方のバインディングを次のように更新できます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は平均を表示するはずです!

ヒント:指定されたXPathをテストするには、 XPath式の評価ツールを提供するXMLツールプラグインでNotepad++を使用できます。

于 2013-03-04T16:26:21.713 に答える