Setting Datacontext

问题描述 投票:-1回答:1

[好,我现在要尝试解释一下自己的锻炼。这是我的PageOverzicht.xaml,此代码有效。它为我提供了一个带有花朵颜色(蓝色,橙色,白色,...)的下拉列表。现在,数据上下文被硬编码以找到白色的花朵。目标:通过后面的代码设置数据上下文,以便下一步可以使用selectionchanged属性选择具有所选颜色的花朵。

所以现在我需要先设置数据上下文,以便它不会硬编码为白色。列表框由xml节点组成,使用PageOverzicht中的Page_Loaded方法,颜色为白色的植物名称。

<Page x:Class="Planten_BIS.PageOverzicht"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:Planten_BIS"
      mc:Ignorable="d"
      d:DesignHeight="450" d:DesignWidth="800"
      Title="PageOverzicht">

    <Page.Resources>
        <XmlDataProvider x:Key="CatalogDataSource" XPath="catalog" Source="data/catalogus.xml"></XmlDataProvider>
        <DataTemplate x:Key="listItemTemplate">
            <StackPanel Orientation="Horizontal">
                <TextBlock Name="ImageName" Visibility="Collapsed" Text="{Binding XPath=botanical, StringFormat=images/{0}.jpg}" />

                <Border BorderBrush="white" BorderThickness="2" CornerRadius="10" Background="{StaticResource AchtergrondKleur}">
                    <Rectangle Width="100" Height="100" RadiusX="10" RadiusY="10">
                        <Rectangle.Fill>
                            <ImageBrush ImageSource="{Binding Text, ElementName=ImageName}" />
                        </Rectangle.Fill>
                    </Rectangle>
                </Border>
                <StackPanel Orientation="Vertical" Margin="10" VerticalAlignment="Center">
                    <ListBoxItem Content="{Binding XPath=common}"/>
                    <ListBoxItem Content="{Binding XPath=price}"/>
                </StackPanel>
            </StackPanel>
        </DataTemplate>
    </Page.Resources>
    <Grid>
        <ListBox Name="ListboxFlowers" Background="Transparent" Foreground="white" DataContext="{Binding Source={StaticResource CatalogDataSource}, XPath=color[@name\=\'White\']/plant}" ItemsSource="{Binding}" ItemTemplate="{StaticResource listItemTemplate}"></ListBox>
    </Grid>
</Page>

来自数据的xml的小部分:

<?xml version="1.0" encoding="ISO8859-1" ?>
<catalog>
  <color name="White">
    <plant>
      <common>Jacob's Ladder</common>
      <botanical>Polemonium caeruleum i</botanical>
      <zone>Annual</zone>
      <light>Shade</light>
      <price>$9.26</price>
      <availability>022199</availability>
      <color>white</color>
      <description>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</description>
    </plant>

带有框架的主窗口至PageOverzicht:

<Window x:Class="Planten_BIS.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
        xmlns:local="clr-namespace:Planten_BIS"
        mc:Ignorable="d"
        Title="Plant Catalog" Height="600" Width="800">
    <Window.Resources>
        <Style x:Key="buttonStyle" TargetType="Button">
            <Setter Property="Background" Value="{StaticResource ToolBarKleur}" />
            <Setter Property="BorderBrush" Value="{StaticResource RandKleur}" />
            <Setter Property="Foreground" Value="{StaticResource LetterKleur}" />
            <Setter Property="Height" Value="30" />
            <Setter Property="Margin" Value="6" />
        </Style>
        <Style x:Key="comboStyle" TargetType="ComboBox">
            <Setter Property="Background" Value="{StaticResource ToolBarKleur}" />
            <Setter Property="BorderBrush" Value="{StaticResource RandKleur}" />
            <Setter Property="Foreground" Value="{StaticResource LetterKleur}" />
            <Setter Property="Width" Value="100" />
            <Setter Property="Height" Value="30" />
            <Setter Property="Margin" Value="6" />
        </Style>
        <XmlDataProvider x:Key="CatalogDataSource" XPath="catalog" Source="data/catalogus.xml"></XmlDataProvider>
        <CollectionViewSource x:Key="cvsColors" Source="{StaticResource CatalogDataSource}">
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="color" />
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>
        <DataTemplate x:Key="comboItemTemplate">
            <Label Content="{Binding XPath=@name}"/>
        </DataTemplate>

    </Window.Resources>
    <DockPanel LastChildFill="True">
        <ToolBar Background="{StaticResource ToolBarKleur}" DockPanel.Dock="Top">
            <Button Style="{StaticResource buttonStyle}" Content="Backward"></Button>
            <Button Style="{StaticResource buttonStyle}" Content="Forward"></Button>
            <ComboBox Style="{StaticResource comboStyle}" SelectedIndex="0"  ItemsSource="{Binding Source={StaticResource CatalogDataSource}, XPath=color}" ItemTemplate="{StaticResource comboItemTemplate}"></ComboBox>
        </ToolBar>
        <Frame Source="PageOverzicht.xaml" Name="frame" NavigationUIVisibility="Hidden">
            <Frame.Background>
                <ImageBrush ImageSource="assets/background.jpg" Stretch="UniformToFill"/>
            </Frame.Background>
        </Frame>
    </DockPanel>
</Window>
wpf data-binding datacontext xmldataprovider
1个回答
0
投票

数据源处理应移至控件,该控件是ComboBoxFrame的公共父级,在这种情况下,我选择了MainWindow

您应该在DependecyProperty上添加所需的MainWindow定义,该定义可用于ComboBox.ItemsSourceComboBox.SelectedItemFrame.DataContext的数据绑定。

对于XML处理,我用XElement数据源替换了XMLDataProvider,该数据源允许LINQ To XML以便舒适地过滤或遍历C#中的XML对象树。

现在ComboBox绑定到表示XML XElement节点的color项目的集合。所选的ComboBox项目是单个XML color元素。 plant的后代color节点用于设置Frame.DataContext,该继承自Page.DataContextListBox中的Page现在将其ItemsSource直接绑定到DataContext,它是MainWindow.PlantsOfSelectedColor属性。或者,例如如果需要将Page.DataContext设置为其他值,则可以让Binding遍历可视树以将MainWindow.PlantsOfSelectedColorRelativeSource FindAncestor用于Binding.RelativeSource,找到ListBox.ItemsSource

MainWindow.xaml.cs

public partial class MainWindow : Window
{
  public static readonly DependencyProperty PlantColorNodesProperty = DependencyProperty.Register(
    "PlantColorNodes",
    typeof(IEnumerable<XElement>),
    typeof(MainWindow),
    new PropertyMetadata(default(IEnumerable<XElement>)));

  public IEnumerable<XElement> PlantColorNodes
  {
    get => (IEnumerable<XElement>) GetValue(MainWindow.PlantColorNodesProperty);
    set => SetValue(MainWindow.PlantColorNodesProperty, value);
  }

  public static readonly DependencyProperty SelectedPlantColorNodeProperty = DependencyProperty.Register(
    "SelectedPlantColorNode",
    typeof(XElement),
    typeof(MainWindow),
    new PropertyMetadata(default(XElement), OnSelectedPlantColorNodeChanged));

  public XElement SelectedPlantColorNode
  {
    get => (XElement) GetValue(MainWindow.SelectedPlantColorNodeProperty);
    set => SetValue(MainWindow.SelectedPlantColorNodeProperty, value);
  }

  public static readonly DependencyProperty PlantsOfSelectedColorProperty = DependencyProperty.Register(
    "PlantsOfSelectedColor",
    typeof(IEnumerable<XElement>),
    typeof(MainWindow),
    new PropertyMetadata(default(IEnumerable<XElement>)));

  public IEnumerable<XElement> PlantsOfSelectedColor
  {
    get => (IEnumerable<XElement>) GetValue(MainWindow.PlantsOfSelectedColorProperty);
    set => SetValue(MainWindow.PlantsOfSelectedColorProperty, value);
  }

  public MainWindow()
  {
    InitializeComponent();

    // Open XML an collect all 'color' nodes
    this.PlantColorNodes = XElement.Load("data/catalogus.xml").Elements("color");
  }

  private static void OnSelectedPlantColorNodeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  {
    var colorNode = e.NewValue as XElement;

    (d as MainWindow).PlantsOfSelectedColor = new List<XElement>(colorNode.Elements());
  }
}

MainWindow.xaml

<Window>
  <DockPanel LastChildFill="True">
    <ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=MainWindow}, Path=PlantColorNodes}" 
              SelectedItem="{Binding RelativeSource={RelativeSource AncestorType=MainWindow}, Path=SelectedPlantColorNode}">
      <ComboBox.ItemTemplate>
        <DataTemplate>
          <TextBlock Text="{Binding Attribute[name].Value}" />
        </DataTemplate>
      </ComboBox.ItemTemplate>
    <ComboBox>
    <Frame DatContext="{Binding RelativeSource={RelativeSource AncestorType=MainWindow}, Path=PlantsOfSelectedColor}"
           Source="PageOverzicht.xaml" />
    </DockPanel>
</Window>

PageOverzicht.xaml

<Page>
  <ListBox ItemsSource="{Binding}">
    <ListBox.ItemTemplate>
      <DataTemplate  >
        <StackPanel Orientation="Horizontal">
          <TextBlock Text="{Binding Element[botanical].Value}" />
          <TextBlock Text="{Binding Element[common].Value}"/>
          <TextBlock Text="{Binding Element[price].Value}"/>          
        </StackPanel>
      </DataTemplate>
    </ListBox.ItemTemplate>
  </ListBox>
</Page>
© www.soinside.com 2019 - 2024. All rights reserved.