如何从我的控件中获取当前的datacontext

时间:2014-01-19 01:11:20

标签: c# wpf xaml

我有一个列表框,其中包含我正在尝试开发的控件选择器。基本上,数据源是XML,我想读取当前上下文来决定要显示哪个元素控件。

为此,我想使用当前项的上下文获取XmlDataProvider,并评估该XML。在XAML中,我会编写{Binding Path = @ label}以从curretn XML元素中检索label属性。从代码背后,我甚至无法确定获取此XML的位置,因为它通过列表控件传递给该控件的类,但不是作为一个可访问的属性,直到我能找到。

无论如何得到@label是不够的;我想在类ControlChooser中的XmlElement对象,在下面实例化。

 <ListBox 
  IsSynchronizedWithCurrentItem="True"
  ItemsSource="{Binding XPath=*[not(self::units)]}"
  >
  <ListBox.ItemTemplate>
    <DataTemplate>
      <W3V:ControlChooser/>
    </DataTemplate>
  </ListBox.ItemTemplate>
  <ListBox.ItemContainerStyle>
    <!-- Force the items to fill all available space. -->
    <Style TargetType="ListBoxItem">
      <Setter 
        Property="VerticalContentAlignment" 
        Value="Stretch" 
        />
    </Style>
  </ListBox.ItemContainerStyle>
</ListBox>

或者,如果您可以建议另一种方式来完成工作(切换显示的控件)....

2 个答案:

答案 0 :(得分:1)

您可以使用多个DataTemplate来设置不同元素类型的样式。如果您熟悉XSLT,则DataTemplatexsl:template的功能相同。

样式示例:

<Window x:Class="ZoomingScrollViewer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <XmlDataProvider x:Key="testData" XPath="/Contacts/*">
            <x:XData>
                <Contacts xmlns="">
                    <Person Name="John" />
                    <Person Name="Robby" />
                    <Business>
                        <ContactName>Jemma</ContactName>
                        <BusinessName>Ars</BusinessName>
                    </Business>
                    <Business>
                        <BusinessName>The other one</BusinessName>
                    </Business>
                </Contacts>
            </x:XData>
        </XmlDataProvider>
    </Window.Resources>
    <Grid>
        <ListBox ItemsSource="{Binding Source={StaticResource testData}}">
            <ListBox.Resources>
                <DataTemplate DataType="Person">
                    <TextBlock Text="{Binding XPath=@PersonName}" />
                </DataTemplate>
                <DataTemplate DataType="Business">
                    <StackPanel>
                        <TextBlock Text="{Binding XPath=ContactName}" />
                        <TextBlock Text="{Binding XPath=BusinessName}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.Resources>
        </ListBox>
    </Grid>
</Window>

如果您想根据属性而不是元素选择DataTemplate,则可以使用DataTemplateSelector运行任意代码,如this question中所述。

答案 1 :(得分:0)

我发现“Different views / data template based on member variable”最接近答案。有了这个想法,我可以制作一个对我有意义的独立控件。这是关键点:

  <DataTrigger Binding="{Binding XPath=@kind}" Value="Number">
     <Setter Property="ContentTemplate" Value="{StaticResource SmallInt}" />
  </DataTrigger>

这是整个控制:

<ContentControl
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:W3V="clr-namespace:W3.Views"
             x:Class="W3.Views.ControlChooser">
  <ContentControl.Resources>
    <DataTemplate x:Key="StringChoice" >
      <W3V:ComboView />
    </DataTemplate>

    <DataTemplate x:Key="SmallInt" >
      <W3V:SpinView />
    </DataTemplate>

  </ContentControl.Resources>
  <ContentControl.Style>
      <Style TargetType="{x:Type ContentControl}">
        <Setter Property="ContentTemplate" Value="{StaticResource StringChoice}" />
        <Style.Triggers>
          <DataTrigger Binding="{Binding XPath=@kind}" Value="Number">
            <Setter Property="ContentTemplate" Value="{StaticResource SmallInt}" />
          </DataTrigger>
        </Style.Triggers>
      </Style>
    </ContentControl.Style>
</ContentControl>