2014-10-07 17 views
5

To jest podobny problem do WPF Binding : Casting in binding path, gdzie muszę rzucić obiekt w oświadczeniu wiążącym XAML. Ale nie potrafię zrozumieć, jak wykonać wiązanie w moim konkretnym przypadku.WPF Casting in Binding Path

Odpowiedź na to pytanie odnosi się do PropertyPath XAML Syntax, a odpowiednią sekcją jest (ja wierzę) Single Property, Attached or Otherwise Type-Qualified.

W moim przypadku, moim głównym widoku modelu Mam słownika, który mapuje ciągi do obiektów, które implementują interfejs bazowy:

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

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

Jednak mam też te dodatkowe przedmioty i interfejsy, które podklasy obiektu podstawowego:

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 {..} 

i ostatecznie I wypełnić mój słownika jak:

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

Teraz w moim XAML mam kontrolę użytkownika do renderowania obiektu Fred, a drugą do renderowania obiektu Wilma. Mogę ustawić kontekstu danych tych kontroli użytkowników robi coś takiego:

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

Jednak moje rozumienie jest to, że będą wystawiać tylko IFlintStone składowe tych obiektów do ich kontroli użytkowników. Ale chcę narażać IFred do <FredControl> i IWilma do <WilmaControl>

Czy to możliwe, a co składnia wiązania byłoby w tym przypadku?

Korzystanie pomysły z linków ja przywołanych wyżej Próbowałem rzeczy jak:

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

i

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

(Gdzie myns jest przestrzeni nazw XAML definicji wskazując na przedmiot Fred w zespole .)

Ale program albo ulega awarii i spala się na starcie, albo skarży się, że nie może znaleźć Fred jako właściwość bieżącego kontekstu danych.

Odpowiedz

9

Oto wersja robocza mojej interpretacji problemu:

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 i WilmaControl.xaml.cs są niezmodyfikowanej (tylko InitializeComponent(); w konstruktorach).

I zrzut ekranu:

enter image description here

+0

Jest to bardzo wyraźny przykład skomplikowanej składni wiążącej. Zastanawiam się, czy IntelliSense działa podczas pisania? –

+0

Brakujące} było ponad stroną. Naprawdę nie mam zajęć o nazwach Fred i Wilma –

+0

@PeterM - usunę tę część z odpowiedzi. Chyba powinienem to sobie uświadomić. Oczywiście znasz składnię wiążącą. –