WPF 在XmlDataProvider上使用主-从绑定(Master-Detail Binding)

来源:互联网 时间:1970-01-01

示例程序:

 

如上程序截图,一目了然典型的主从模式绑定应用,如果里面的数据不是用XML来存储而是已经初始化好的C#对象(比如国家是Country类的对象,名字是Name属性,Provinces属性保存一个Province集合,代表国家的省/州,Province类包含Name属性代表名称,Cities属性代表一些列City类对象……)那么主从模式绑定可以很简单的这样写:

1. 设置最外层DataContext为一系列的“国家”(“国家”集合)

2. 国家ListBox直接绑定

3. 省/州ListBox的ItemsSource为: {Binding Path=Provinces} (或者/Provinces)

4. 城市ListBox的ItemsSource为: {Binding Path=Province/Cities}

(注意所有ListBox的IsSynchronizedWithCurrentItem都设置成True)

但是如果放在Xml数据上,由于绑定上要用到XPath属性而不是Path属性,因此上述传统方案不适用,解决方案就是通过直接绑定所属ListBox的SelectedItem值,然后再在这个值上进行XPath查询。注意第二层绑定直接用XPath,没有绑定最外层ListBox的SelectedItem。ListBox代码如下:

        <HeaderedContentControl Header="国家">            <ListBox 

                ItemsSource="{Binding}"

                DisplayMemberPath="@name"

                IsSynchronizedWithCurrentItem="True"></ListBox>

        </HeaderedContentControl>

        <HeaderedContentControl Header="省/州" 

                                Grid.Column="1">

            <ListBox Name="lbxProvince"

                     ItemsSource="{Binding XPath=province}"

                     DisplayMemberPath="@name"

                     IsSynchronizedWithCurrentItem="True"></ListBox>

        </HeaderedContentControl>

        <HeaderedContentControl Header="城市" 

                                Grid.Column="2">

            <ListBox DataContext="{Binding ElementName=lbxProvince, Path=SelectedItem}"

                     ItemsSource="{Binding XPath=city}"

                     IsSynchronizedWithCurrentItem="True"></ListBox>

        </HeaderedContentControl>

 

完整的XAML代码

    <Window.Resources>

        <XmlDataProvider x:Key="xml" XPath="/countries/country">

            <!-- 示例数据 -->

            <x:XData>

                <countries xmlns="">

                    <country name="中国">

                        <province name="陕西">

                            <city>西安</city>

                            <city>宝鸡</city>

                        </province>

                        <province name="山西">

                            <city>太原</city>

                            <city>大同</city>

                        </province>

                        <province name="内蒙古自治区">

                            <city>呼和浩特</city>

                            <city>包头</city>

                            <city>集宁</city>

                        </province>

                        <province name="河北">

                            <city>石家庄</city>

                            <city>保定</city>

                        </province>

                    </country>

                    <country name="美国">

                        <province name="加利福尼亚">

                            <city>洛杉矶</city>

                            <city>圣迭戈</city>

                        </province>

                        <province name="福罗里达">

                            <city>杰克逊维尔</city>

                            <city>迈阿密</city>

                        </province>

                    </country>

                </countries>

            </x:XData>

        </XmlDataProvider>

        

        <Style TargetType="HeaderedContentControl">

            <Setter Property="Template">

                <Setter.Value>

                    <ControlTemplate TargetType="HeaderedContentControl">

                        <DockPanel>

                            <Border DockPanel.Dock="Top" 

                                    Margin="3" 

                                    CornerRadius="3" 

                                    Background="DarkRed">

                                <TextBlock Text="{TemplateBinding Header}"

                                           HorizontalAlignment="Center"

                                           Foreground="White"></TextBlock>

                            </Border>

                            <ContentPresenter ContentSource="Content"

                                              ContentTemplate="{TemplateBinding ContentTemplate}"></ContentPresenter>

                        </DockPanel>

                    </ControlTemplate>

                </Setter.Value>

            </Setter>

        </Style>

 

        <Style TargetType="ListBoxItem">

            <Setter Property="SnapsToDevicePixels" Value="true"/>

            <Setter Property="OverridesDefaultStyle" Value="true"/>

            <Setter Property="Template">

                <Setter.Value>

                    <ControlTemplate TargetType="ListBoxItem">

                        <Border 

                              Name="Border"

                              Padding="2"

                              SnapsToDevicePixels="true">

                            <ContentPresenter />

                        </Border>

                        <ControlTemplate.Triggers>

                            <Trigger Property="IsSelected" Value="true">

                                <Setter TargetName="Border" Property="Background" Value="YellowGreen"/>

                            </Trigger>

                        </ControlTemplate.Triggers>

                    </ControlTemplate>

                </Setter.Value>

            </Setter>

        </Style>

 

    </Window.Resources>

    <Grid DataContext="{Binding Source={StaticResource xml}}">

        <Grid.ColumnDefinitions>

            <ColumnDefinition></ColumnDefinition>

            <ColumnDefinition></ColumnDefinition>

            <ColumnDefinition></ColumnDefinition>

        </Grid.ColumnDefinitions>

        <HeaderedContentControl Header="国家">

            <ListBox 

                ItemsSource="{Binding}"

                DisplayMemberPath="@name"

                IsSynchronizedWithCurrentItem="True"></ListBox>

        </HeaderedContentControl>

        <HeaderedContentControl Header="省/州" 

                                Grid.Column="1">

            <ListBox Name="lbxProvince"

                     ItemsSource="{Binding XPath=province}"

                     DisplayMemberPath="@name"

                     IsSynchronizedWithCurrentItem="True"></ListBox>

        </HeaderedContentControl>

        <HeaderedContentControl Header="城市" 

                                Grid.Column="2">

            <ListBox DataContext="{Binding ElementName=lbxProvince, Path=SelectedItem}"

                     ItemsSource="{Binding XPath=city}"

                     IsSynchronizedWithCurrentItem="True"></ListBox>

        </HeaderedContentControl>

    </Grid>

本文来自_Mgen的博客,原文地址:http://www.cnblogs.com/mgen/archive/2011/06/19/2084553.html


相关阅读:
Top