【问题标题】:WPF Casting in Binding Path绑定路径中的 WPF 强制转换
【发布时间】:2014-12-02 09:00:48
【问题描述】:

这是与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 暴露给&lt;FredControl&gt;IWilma 暴露给&lt;WilmaControl&gt;

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

使用我上面引用的链接中的想法,我尝试了以下方法:

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

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

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

但程序要么在启动时崩溃并烧毁,要么抱怨找不到Fred 作为当前数据上下文的属性。

【问题讨论】:

    标签: wpf xaml binding casting


    【解决方案1】:

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

    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(); 在构造函数中)。

    还有截图:

    【讨论】:

    • 这是一个非常清楚的复杂绑定语法示例。我想知道 IntelliSense 在您输入时是否有效?
    • 丢失的 } 是一个过度的网站.. 我真的没有名为 Fred 和 Wilma 的课程
    • @PeterM - 我将从答案中删除该部分。我想我应该意识到这一点。当然你会知道绑定语法。
    • 看起来你的例子正是我的意思。看起来我做了一个毫无根据的假设,即 UserControls 只会看到基本接口(@98​​7654326@)而不是最广泛的接口(@98​​7654327@ 和IWilma)。在主窗口的附加 texblocks 中进行转换不是我需要做的,但感谢你的语法!
    • OK .. 现在我看到了转换适合的位置 .. 在用户控件本身的类定义中!
    猜你喜欢
    • 2013-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多