WPF在绑定路径中进行转换

时间:2014-10-07 20:10:49

标签: wpf xaml binding casting

这与WPF Binding : Casting in binding path类似,我需要在XAML绑定语句中强制转换对象。但我似乎无法理解如何在我的特定情况下制作绑定。

该问题的答案代表PropertyPath XAML Syntax,相关部分是(我相信)Single Property, Attached or Otherwise Type-Qualified

就我而言,在我的主视图模型中,我有一个字典,它将字符串映射到实现基接口的对象:

Dictionary<string, IFlintStone> FlintStones { get; set;}

public interface IFlintStone { Walk, Talk etc}
public class FlintStone : IFlintStone { .. }

但是我还有这些额外的对象和接口,它们是基础对象的子类:

public interface IFred : IFlintStone { Eat, Drink, Yell etc }
public interface IWilma : IFlintStone { Wash, Clean, Cook etc }

public class Fred : FlintStone, IFred {..}
public class Wilma : FlintStone, IWilma {..}

最后我填写了我的字典:

FlintStones["Fred"] = new Fred();
FlintStones["Wilma"] = new Wilma();

现在,在我的XAML中,我有一个用户控件用于呈现Fred对象,另一个用于呈现Wilma对象。我可以设置这些用户控件的数据上下文,例如:

<FredControl DataContext="{Binding Path=FlintStones[Fred]}" />
<WilmaControl DataContext="{Binding Path=FlintStones[Wilma]}" />

但我的理解是,这只会将这些对象的IFlintStone组件暴露给各自的用户控件。但我想将IFred公开给<FredControl>IWilma公开<WilmaControl>

这是可能的,在这种情况下绑定语法是什么?

使用上面引用的链接中的提示,我尝试过以下方法:

<FredControl DataContext="{Binding path=(myns:Fred.FlintStones[Fred])}" />

<FredControl DataContext="{Binding path=(myns:Fred).FlintStones[Fred]}" />

(其中myns是指向程序集中Fred对象的xaml名称空间定义。)

但该程序在启动时崩溃并烧毁,或者它抱怨它无法找到Fred作为当前数据上下文的属性。

1 个答案:

答案 0 :(得分:9)

以下是我对您的问题的解释的工作版本:

MainWindow.xaml

<Window x:Class="WpfApplication22.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication22"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <TextBlock Text="{Binding Path=FlintStones[Fred].FlintStone}" />
        <TextBlock Text="{Binding Path=FlintStones[Fred].(local:Fred.Yell)}" />
        <local:FredControl DataContext="{Binding Path=FlintStones[Fred]}" />
        <TextBlock />
        <TextBlock Text="{Binding Path=FlintStones[Wilma].FlintStone}" />
        <TextBlock Text="{Binding Path=FlintStones[Wilma].(local:Wilma.Clean)}" />
        <local:WilmaControl DataContext="{Binding Path=FlintStones[Wilma]}" />
    </StackPanel>
</Window>

MainWindow.xaml.cs

using System.Windows;
using System.Collections.Generic;

namespace WpfApplication22
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public Dictionary<string, IFlintStone> FlintStones { get; set; }

        public MainWindow()
        {
            InitializeComponent();

            FlintStones = new Dictionary<string, IFlintStone>();
            FlintStones["Fred"] = new Fred();
            FlintStones["Wilma"] = new Wilma();

            this.DataContext = this;
        }
    }

    public interface IFlintStone
    {
        string FlintStone { get; set; }
    }
    public interface IFred : IFlintStone
    {
        string Yell { get; set; }
    }
    public interface IWilma : IFlintStone
    {
        string Clean { get; set; }
    }

    public class Fred : IFred
    {
        public string FlintStone { get; set; }
        public string Yell { get; set; }

        public Fred()
        {
            FlintStone = "Fred Flintstone";
            Yell = "Yabba Dabba Doo";
        }
    }

    public class Wilma : IWilma
    {
        public string FlintStone { get; set; }
        public string Clean { get; set; }

        public Wilma()
        {
            FlintStone = "Wilma Flintstone";
            Clean = "Mammoth Dish Washer";
        }
    }
}

FredControl.xaml

<UserControl x:Class="WpfApplication22.FredControl"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel Background="Beige">
        <TextBlock Text="{Binding FlintStone}" />
        <TextBlock Text="{Binding Yell}" />
    </StackPanel>
</UserControl>

WilmaControl.xaml

<UserControl x:Class="WpfApplication22.WilmaControl"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel Background="AntiqueWhite">
        <TextBlock Text="{Binding FlintStone}" />
        <TextBlock Text="{Binding Clean}" />
    </StackPanel>
</UserControl>

FredControl.xaml.cs和WilmaControl.xaml.cs未经修改(只是在构造函数中的InitializeComponent();.

截图:

enter image description here