none
WPF DataGrid(3.5)绑定XML的问题 RRS feed

  • 问题

  • XML部分节点:

    					<Audios>
    						<Audio>
    							<Content>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</Content>
    							<DolbyE>
    								<Channels5_1>
    									<ChannelSpecificContent>
    										<Left>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</Left>
    										<Right>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</Right>
    										<Center>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</Center>
    										<LowFrequency>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</LowFrequency>
    										<LeftSurround>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</LeftSurround>
    										<RightSurround>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</RightSurround>
    									</ChannelSpecificContent>
    									<EmbeddedIn>AES1</EmbeddedIn>
    								</Channels5_1>
    							</DolbyE>
    						</Audio>
    						<at:Audio>
    							<at:Content>bbbbbbbbbbbbbbbbbbbbbbbbb</at:Content>
    							<at:DolbyE>
    								<at:Channels5_1>
    									<at:ChannelSpecificContent>
    										<at:Left>bbbbbbbbbbbbbbbbbb</at:Left>
    										<at:Right>bbbbbbbbbbbbbbbbb</at:Right>
    										<at:Center>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</at:Center>
    										<at:LowFrequency>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</at:LowFrequency>
    										<at:LeftSurround>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</at:LeftSurround>
    										<at:RightSurround>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</at:RightSurround>
    									</at:ChannelSpecificContent>
    									<at:EmbeddedIn>AES1</at:EmbeddedIn>
    								</at:Channels5_1>
    							</at:DolbyE>
    						</at:Audio>
    					</Audios>

    这个XML的Audios中的Audio是有at前缀的,,我为了做测试把第一个Audio元素的前缀at给删掉了

    XML的命名控件已经都应设好了

    问题是这样.当绑定不带前缀的Audios到DataGrid时,可以成功并在DataGrid中显示两条记录,绑定带前缀的at:Audios时在DataGrid中也可以显示两行但是Cell的内容为空

    如果将带前缀的at:Audio中的某一个元素添加到到TextBlock时可以显示内容

    例如:

     <TextBlock HorizontalAlignment="Left" Margin="71,10,0,0" Style="{StaticResource contentStyle}" Text="{Binding      XPath=Audios/at:Audio/*/*/at:ChannelSpecificContent/at:Left}" VerticalAlignment="Top" />   这个可以显示Left节点的内容

    在DataGrid中:

                        <my:DataGrid Name="dgTest" MaxHeight="150" MinHeight="0" DataContext="{Binding XPath=Audios}"  ItemsSource="{Binding XPath=at:Audio}" HorizontalAlignment="Stretch" Margin="10"  VerticalAlignment="Top">
                            <my:DataGrid.Columns>
                                <my:DataGridTextColumn Header="AAA" Binding="{Binding XPath=*/*/at:ChannelSpecificContent/at:Left}"/>
                            </my:DataGrid.Columns>
                        </my:DataGrid>   

    这样绑定就会失败.DataGrid显示两个空行

    当去掉at:前缀时是可以绑定并显示节点内容的

    我个人在 <my:DataGridTextColumn Header="AAA" Binding="{Binding XPath=*/*/at:ChannelSpecificContent/at:Left}"/>加了一个Converter并在Converter中加了断点发现根本没有执行,只有找不到这个节点的时候才不会发生绑定..个人认为在DataGrid中是不是要添加at对应的命名空间...

    希望高手解答..谢谢



    我是一只猪

    2012年3月19日 15:04

答案

  • 所谓的XML元素前缀就是XMLNS XML映射的名字空间,如果你没有在XML中映射at的名字空间,这个前缀是没有意义的。 在有了xmlns的定义情况下,WPF 需要XmlDataProvider 来指定 XmlNamespaceManager 属性,当然Binding过程中,对于DataGrid 也需要指定XmlNamespaceManager 附加属性。 我的测试代码如下:

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit"
            Title="MainWindow" Height="350" Width="525">
      <Window.Resources>
        <XmlNamespaceMappingCollection x:Key="map">
          <XmlNamespaceMapping Prefix="at" Uri="http://mynamespace"/>
        </XmlNamespaceMappingCollection>
        <XmlDataProvider x:Key="source" XPath="." XmlNamespaceManager="{StaticResource map}">
          <x:XData>
            <Audios xmlns="" xmlns:at="http://mynamespace">
              <Audio>
                <Content>content1</Content>
                <DolbyE>
                  <Channels5_1>
                    <ChannelSpecificContent>
                      <Left>left1</Left>
                      <Right>right1</Right>
                      <Center>center1</Center>
                      <LowFrequency>LowFrequency1</LowFrequency>
                      <LeftSurround>LeftSurround1</LeftSurround>
                      <RightSurround>RightSurround1</RightSurround>
                    </ChannelSpecificContent>
                    <EmbeddedIn>AES1</EmbeddedIn>
                  </Channels5_1>
                </DolbyE>
              </Audio>
              <at:Audio>
                <at:Content>content2</at:Content>
                <at:DolbyE>
                  <at:Channels5_1>
                    <at:ChannelSpecificContent>
                      <at:Left>left2</at:Left>
                      <at:Right>right2</at:Right>
                      <at:Center>center2</at:Center>
                      <at:LowFrequency>LowFrequency2</at:LowFrequency>
                      <at:LeftSurround>LeftSurround2</at:LeftSurround>
                      <at:RightSurround>RightSurround2</at:RightSurround>
                    </at:ChannelSpecificContent>
                    <at:EmbeddedIn>AES1</at:EmbeddedIn>
                  </at:Channels5_1>
                </at:DolbyE>
              </at:Audio>
            </Audios>
          </x:XData>
        </XmlDataProvider>
      </Window.Resources>
      <Window.DataContext>
        <StaticResource ResourceKey="source"/>
      </Window.DataContext>
      <StackPanel>
        <TextBlock Text="{Binding XPath=Audios/at:Audio/*/*/at:ChannelSpecificContent/at:Left}" />
        <my:DataGrid Name="dgTest" MaxHeight="150" MinHeight="0" DataContext="{Binding XPath=Audios}" 
                     ItemsSource="{Binding XPath=at:Audio}"  Binding.XmlNamespaceManager="{StaticResource map}"
                     AutoGenerateColumns="false" CanUserAddRows="False">
          <my:DataGrid.Columns>
            <my:DataGridTextColumn Header="AAA" Binding="{Binding XPath=*/*/at:ChannelSpecificContent/at:Left}"/>
          </my:DataGrid.Columns>
        </my:DataGrid>
      </StackPanel>
    </Window>
    


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年3月20日 6:06
    版主

全部回复

  • 所谓的XML元素前缀就是XMLNS XML映射的名字空间,如果你没有在XML中映射at的名字空间,这个前缀是没有意义的。 在有了xmlns的定义情况下,WPF 需要XmlDataProvider 来指定 XmlNamespaceManager 属性,当然Binding过程中,对于DataGrid 也需要指定XmlNamespaceManager 附加属性。 我的测试代码如下:

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit"
            Title="MainWindow" Height="350" Width="525">
      <Window.Resources>
        <XmlNamespaceMappingCollection x:Key="map">
          <XmlNamespaceMapping Prefix="at" Uri="http://mynamespace"/>
        </XmlNamespaceMappingCollection>
        <XmlDataProvider x:Key="source" XPath="." XmlNamespaceManager="{StaticResource map}">
          <x:XData>
            <Audios xmlns="" xmlns:at="http://mynamespace">
              <Audio>
                <Content>content1</Content>
                <DolbyE>
                  <Channels5_1>
                    <ChannelSpecificContent>
                      <Left>left1</Left>
                      <Right>right1</Right>
                      <Center>center1</Center>
                      <LowFrequency>LowFrequency1</LowFrequency>
                      <LeftSurround>LeftSurround1</LeftSurround>
                      <RightSurround>RightSurround1</RightSurround>
                    </ChannelSpecificContent>
                    <EmbeddedIn>AES1</EmbeddedIn>
                  </Channels5_1>
                </DolbyE>
              </Audio>
              <at:Audio>
                <at:Content>content2</at:Content>
                <at:DolbyE>
                  <at:Channels5_1>
                    <at:ChannelSpecificContent>
                      <at:Left>left2</at:Left>
                      <at:Right>right2</at:Right>
                      <at:Center>center2</at:Center>
                      <at:LowFrequency>LowFrequency2</at:LowFrequency>
                      <at:LeftSurround>LeftSurround2</at:LeftSurround>
                      <at:RightSurround>RightSurround2</at:RightSurround>
                    </at:ChannelSpecificContent>
                    <at:EmbeddedIn>AES1</at:EmbeddedIn>
                  </at:Channels5_1>
                </at:DolbyE>
              </at:Audio>
            </Audios>
          </x:XData>
        </XmlDataProvider>
      </Window.Resources>
      <Window.DataContext>
        <StaticResource ResourceKey="source"/>
      </Window.DataContext>
      <StackPanel>
        <TextBlock Text="{Binding XPath=Audios/at:Audio/*/*/at:ChannelSpecificContent/at:Left}" />
        <my:DataGrid Name="dgTest" MaxHeight="150" MinHeight="0" DataContext="{Binding XPath=Audios}" 
                     ItemsSource="{Binding XPath=at:Audio}"  Binding.XmlNamespaceManager="{StaticResource map}"
                     AutoGenerateColumns="false" CanUserAddRows="False">
          <my:DataGrid.Columns>
            <my:DataGridTextColumn Header="AAA" Binding="{Binding XPath=*/*/at:ChannelSpecificContent/at:Left}"/>
          </my:DataGrid.Columns>
        </my:DataGrid>
      </StackPanel>
    </Window>
    


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    2012年3月20日 6:06
    版主
  • 伟大的Bob Bao

    Binding.XmlNamespaceManager 就是这个地方,我找了半天都没找到

    谢谢谢谢...灰常感谢


    我是一只猪

    2012年3月20日 7:48