好的,我现在要试着解释一下我的运动。。这是我的PageOverzicht.xaml,此代码有效。它给了我一个下拉列表,里面有花的颜色(蓝色、橙色、白色…(。现在数据上下文被硬编码以查找白色的花。目标:通过代码隐藏设置datacontext,以便下一步可以使用selectionchanged属性来选择具有所选颜色的花。
所以现在我需要先设置datacontext,这样它就不会硬编码为白色。。Listbox由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>
数据源处理应该移动到一个控件,该控件是ComboBox
和Frame
的公共父级,在这种情况下,我选择了MainWindow
。
您应该将所需的DependecyProperty
定义添加到MainWindow
中,该定义可用于ComboBox.ItemsSource
、ComboBox.SelectedItem
和Frame.DataContext
的数据绑定。
对于XML处理,我用XElement
数据源替换了XMLDataProvider,该数据源允许LINQ To XML轻松地过滤或遍历C#中的XML对象树。
现在,ComboBox
绑定到表示XMLcolor
节点的XElement
项的集合。所选择的ComboBox
项是单个XMLcolor
元素。color
的子代plant
节点用于设置继承到Page.DataContext
的Frame.DataContext
。Page
中的ListBox
现在将其ItemsSource
直接绑定到作为MainWindow.PlantsOfSelectedColor
属性的DataContext
。或者,例如,如果您需要将Page.DataContext
设置为不同的值,则可以让Binding
遍历视觉树,使用RelativeSource FindAncestor
查找MainWindow.PlantsOfSelectedColor
,以查找ListBox.ItemsSource
的Binding.RelativeSource
。
主窗口.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;
// Get the 'plant' child nodes of the selected 'color' node
(d as MainWindow).PlantsOfSelectedColor = colorNode.Elements();
}
}
主窗口.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>