绑定路径中的 WPF 转换
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26244400/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF Casting in Binding Path
提问by Peter M
This is a similar problem to WPF Binding : Casting in binding path, where I need to cast an object in a XAML binding statement. But I can't seem to understand how to craft the binding in my particular case.
这是一个类似于WPF 绑定的问题:在绑定路径中进行转换,我需要在 XAML 绑定语句中转换一个对象。但我似乎无法理解如何在我的特定情况下制作绑定。
The answer to that question references PropertyPath XAML Syntax, and the relevant section is (I believe) Single Property, Attached or Otherwise Type-Qualified.
该问题的答案引用了PropertyPath XAML Syntax,相关部分是 (我相信) Single Property, Attached or Otherwise Type-Qualified。
In my case, in my main View Model I have a dictionary that maps strings to objects that implement a base interface:
就我而言,在我的主视图模型中,我有一个将字符串映射到实现基本接口的对象的字典:
Dictionary<string, IFlintStone> FlintStones { get; set;}
public interface IFlintStone { Walk, Talk etc}
public class FlintStone : IFlintStone { .. }
However I also have these additional objects and interfaces which subclass the base object:
但是,我还有这些附加对象和接口,它们是基对象的子类:
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 {..}
And eventually I populate my dictionary like:
最终我填充我的字典,如:
FlintStones["Fred"] = new Fred();
FlintStones["Wilma"] = new Wilma();
Now, in my XAML I have a user control for rendering a Fredobject, and another one for rendering a Wilmaobject. I can set the data context of these user controls doing something like:
现在,在我的 XAML 中,我有一个用于呈现Fred对象的用户控件,以及另一个用于呈现Wilma对象的用户控件。我可以设置这些用户控件的数据上下文,执行如下操作:
<FredControl DataContext="{Binding Path=FlintStones[Fred]}" />
<WilmaControl DataContext="{Binding Path=FlintStones[Wilma]}" />
However my understanding is that this will only expose the IFlintStonecomponents of those objects to their respective user controls. But I want to expose IFredto the <FredControl>and IWilmato the <WilmaControl>
但是我的理解是,这只会将IFlintStone这些对象的组件暴露给它们各自的用户控件。但我想暴露IFred给<FredControl>和IWilma给<WilmaControl>
Is this possible and what would the binding syntax be in this case?
这是可能的,在这种情况下绑定语法是什么?
Using ideas from the links I referenced above, I have tried things like:
使用我上面引用的链接中的想法,我尝试了以下方法:
<FredControl DataContext="{Binding path=(myns:Fred.FlintStones[Fred])}" />
and
和
<FredControl DataContext="{Binding path=(myns:Fred).FlintStones[Fred]}" />
(Where mynsis an xaml namespace definition pointing to the Fredobject in the assembly.)
(myns指向Fred程序集中对象的 xaml 命名空间定义在哪里。)
But the program either crashes and burns on start, or it complains that it can't find Fredas a property of the current data context.
但是程序要么在启动时崩溃并烧毁,要么抱怨它无法Fred作为当前数据上下文的属性找到。
回答by J.H.
Here is a working version of my interpretation of your issue:
这是我对您的问题的解释的工作版本:
MainWindow.xaml
主窗口.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
主窗口.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
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
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 and WilmaControl.xaml.cs are unmodified (just InitializeComponent(); in the constructors).
FredControl.xaml.cs 和 WilmaControl.xaml.cs 未修改(仅 InitializeComponent(); 在构造函数中)。
And a screenshot:
和截图:



