2016-07-22 9 views
1

Ich habe eine Reihe von Auswahlfelder und Textfelder wie folgt aus:IValueConverter - Quelle und Converter in der gleichen Bindung/Same Steuerung über die Quelle und Converter

C1                   T1

C2                   T2

C3                   T3

implementiert I eine IValueConverter die Zeitzone in C1 einzustellen und die entsprechende Zeit in T1 zu erhalten. Gleiches gilt für die anderen Paare.

Was ich tun möchte ist: Wenn ein Benutzer manuell die Zeit in T1 ändert, muss die Zeit in T2 und T3 entsprechend T1 sowie entsprechend der TimeZone ändern.

T1 ist jedoch nicht die Referenz. Wenn für einen der Textfelder der Wert geändert wird, müssen sich auch alle anderen Textfelder ändern.

Diese Änderung kann passieren:

  1. Wenn die Time-Zone in der Combobox geändert wird

  2. , wenn die Nutzer die Zeit manuell ändern, indem in dem Textfeld eingeben

Hier ist mein voller Code:

public partial class MainWindow : Window 
{ 
    public static int num; 
    public static bool isUserInteraction; 
    public static DateTime timeAll; 
    public MainWindow() 
    { 
     InitializeComponent(); 
     this.DataContext = this; 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     ReadOnlyCollection<TimeZoneInfo> TimeZones = TimeZoneInfo.GetSystemTimeZones(); 

     this.DataContext = TimeZones; 

     cmb_TZ1.SelectedIndex = 98; 
     cmb_TZ2.SelectedIndex = 46; 
     cmb_TZ3.SelectedIndex = 84; 
     cmb_TZ4.SelectedIndex = 105; 
     cmb_TZ5.SelectedIndex = 12; 
    } 

    private void ComboBox_Selection(object Sender, SelectionChangedEventArgs e) 
     { 
     var cmbBox = Sender as ComboBox; 

     DateTime currTime = DateTime.UtcNow; 
     TimeZoneInfo tst = (TimeZoneInfo)cmbBox.SelectedItem; 
     if (isUserInteraction) 
     { 
      /* txt_Ctry1.Text= 
       txt_Ctry2.Text = 
       txt_Ctry3.Text = 
       txt_Ctry4.Text = 
       txt_Ctry5.Text =*/ 
      isUserInteraction = false; 
     } 
    } 

    private void TextBox_Type(object Sender, TextChangedEventArgs e) 
    { 
    var txtBox = Sender as TextBox; 

     if (isUserInteraction) 
     { 
      timeAll = DateTime.Parse(txtBox.Text); 
      if (txtBox.Name != "txt_Ctry1") 
      txt_Ctry1.Text= 
         if (txtBox.Name != "txt_Ctry2") 
       txt_Ctry2.Text = 
         if (txtBox.Name != "txt_Ctry3") 
       txt_Ctry3.Text = 
         if (txtBox.Name != "txt_Ctry4") 
       txt_Ctry4.Text = 
         if (txtBox.Name != "txt_Ctry5") 
       txt_Ctry5.Text = 
      isUserInteraction = false; 
     } 
    } 


    private void OnPreviewMouseDown(object sender, MouseButtonEventArgs e) 
    { 
     isUserInteraction = true; 
    } 
} 
public class TimeZoneConverter : IValueConverter 
{ 
    public object Convert(
     object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (MainWindow.isUserInteraction == false) 
     { 
      return value == null ? string.Empty : TimeZoneInfo 
       .ConvertTime(DateTime.UtcNow, TimeZoneInfo.Utc, (TimeZoneInfo)value) 
       .ToString("HH:mm:ss dd MMM yy"); 
     } 
else 
     { 
      return value == null ? string.Empty : TimeZoneInfo 
      .ConvertTime(MainWindow.timeAll, TimeZoneInfo.Utc, (TimeZoneInfo)value) 
      .ToString("HH:mm:ss dd MMM yy"); 
     } 

      } 

    public object ConvertBack(
     object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotSupportedException(); 
    } 
} 

}

XAML:

<Window x:Class="Basic_WorldClock.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:src="clr-namespace:System;assembly=mscorlib" 
    xmlns:sys="clr-namespace:System;assembly=System.Core" 
    xmlns:local="clr-namespace:Basic_WorldClock" 
    mc:Ignorable="d" 
    Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded"> 

    <Window.Resources> 
    <ObjectDataProvider x:Key="timezone" ObjectType="{x:Type  
    sys:TimeZoneInfo}" MethodName="GetSystemTimeZones"> 
    </ObjectDataProvider> 
     <local:TimeZoneConverter x:Key="timezoneconverter"/> 
    </Window.Resources> 

    <Grid Margin="0,0.909,0,-0.909"> 

    <TextBox x:Name="txt_Time1" Text="{Binding ElementName=cmb_TZ1, Path=SelectedValue, Converter={StaticResource timezoneconverter}}" VerticalAlignment="Top"/> 
    <TextBox x:Name="txt_Time2" Text="{Binding ElementName=cmb_TZ2, Path=SelectedValue, Converter={StaticResource timezoneconverter}}" VerticalAlignment="Top"/> 
    <TextBox x:Name="txt_Time3" Text="{Binding ElementName=cmb_TZ3, Path=SelectedValue, Converter={StaticResource timezoneconverter}}" Height="23.637" VerticalAlignment="Bottom"/> 

    <ComboBox x:Name="cmb_TZ1" SelectionChanged="ComboBox_Selection" PreviewMouseDown="OnPreviewMouseDown" ItemsSource="{Binding Source={StaticResource timezone}}" HorizontalAlignment="Right" Height="22.667" Margin="0,89.091,51.667,0" VerticalAlignment="Top" Width="144.666"/> 
    <ComboBox x:Name="cmb_TZ2" SelectionChanged="ComboBox_Selection" PreviewMouseDown="OnPreviewMouseDown" ItemsSource="{Binding Source={StaticResource timezone}}" HorizontalAlignment="Right" Height="22.667" Margin="0,131.091,52.667,0" VerticalAlignment="Top" Width="144.666"/> 
    <ComboBox x:Name="cmb_TZ3" SelectionChanged="ComboBox_Selection" PreviewMouseDown="OnPreviewMouseDown" ItemsSource="{Binding Source={StaticResource timezone}}" HorizontalAlignment="Right" Height="22.667" Margin="0,0,48.334,123.575" VerticalAlignment="Bottom" Width="144.666"/> 


</Grid> 

Frage: Wie kann kaskadieren ich die entsprechenden Änderungen an anderen Textfelder durch die Methode Konvertieren auf die gleiche Weise mit dem Combox tut das? Ich kann die TextChanged-Methode verwenden, um Änderungen in dem Referenztextfeld zu erfassen, und ich kann einige Zeilen Code hinzufügen, um diese Änderungen vorzunehmen, aber ich möchte den IValueConverter verwenden. Kann ich die Quelle und den Konverter in derselben Bindung für eine Textbox haben?

Antwort

1

Ohne eine gute Minimal, Complete, and Verifiable code example, die deutlich zeigt, was Sie bisher haben, ist es schwierig, genaue Informationen zur Verfügung zu stellen. Aber basierend auf dem, was Sie beschrieben haben, scheint es das Hauptproblem hier zu sein, dass Sie nicht die normalen "View Model" -basierten Techniken verwenden, für die WPF entwickelt wurde.Darüber hinaus binden Sie die -Eigenschaft an die Zeitzone und nicht an die Uhrzeit. Daher möchte WPF, wenn die Text-Eigenschaft geändert wird, tatsächlich die Auswahl des Kombinationsfelds und nicht die Uhrzeit selbst.

Das erste, was Sie tun müssen, ist, anstatt Ihre Kontrollen beziehen sich zueinander zu haben, einen Blick Modellklasse erstellen, die den aktuellen Status Sie anzeigen möchten, darstellt, und dann, dass im Fenster für Ihre DataContext verwenden Binden geeigneter Eigenschaften an die jeweiligen Steuerelemente.

Und was sind diese geeigneten Eigenschaften? Nun, basierend auf Ihrer Beschreibung haben Sie eigentlich nur vier: 1) Die tatsächliche Zeit und 2) bis 4) die drei Zeitzonen, die Sie behandeln möchten.

So etwas wie folgt aus:

class ViewModel : INotifyPropertyChanged 
{ 
    // The actual time. Similar to the "timeAll" field you have in the code now 
    // Should be kept in UTC 
    private DateTime _time; 

    // The three selected TimeZoneInfo values for the combo boxes 
    private TimeZoneInfo _timeZone1; 
    private TimeZoneInfo _timeZone2; 
    private TimeZoneInfo _timeZone3; 

    public DateTime Time 
    { 
     get { return _time; } 
     set { UpdateValue(ref _time, value); } 
    } 

    public TimeZoneInfo TimeZone1 
    { 
     get { return _timeZone1; } 
     set { UpdateValue(ref _timeZone1, value); } 
    } 

    public TimeZoneInfo TimeZone2 
    { 
     get { return _timeZone2; } 
     set { UpdateValue(ref _timeZone2, value); } 
    } 

    public TimeZoneInfo TimeZone3 
    { 
     get { return _timeZone3; } 
     set { UpdateValue(ref _timeZone3, value); } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void UpdateValue<T>(ref T field, T value, [CallerMemberName] string propertyName = null) 
    { 
     if (!object.Equals(field, value)) 
     { 
      field = value; 
      PropertyChangedEventHandler handler = PropertyChanged; 

      if (handler != null) 
      { 
       handler(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 
} 

(kapseln Menschen oft die PropertyChanged Ereignis und UpdateValue() Methode in einer Basisklasse, die für alle Ihre Ansicht Modelltypen wiederverwendet werden kann.)

Damit dann schreiben Sie eine Implementierung von IMultiValueConverter, die als Eingabe den Kombinationsfeldindex (dh Index1, Index2 oder Index3 wie angemessen) und den Eigenschaftswert Time verwendet, diese beiden Werte verwendet, um den zeitzonenkonvertierten Wert für th zu erzeugen e Textfeld, das mit diesen beiden Werten und dem Konverter gebunden wird.

Die Convert() Methode des Konverters führt die obige Konvertierung aus. Dann müssen Sie die Methode ConvertBack() verwenden, um den entsprechenden Kombinationsfeldwert für die Konvertierung in die UTC-Zeit zu verwenden.

Leider gibt es hier ein bisschen eine Falte. Ihr Konverter hat normalerweise keinen Zugriff auf diesen Wert. Die IMultiValueConverter.ConvertBack()-Methode ruft nur den gebundenen Zielwert ab und es wird erwartet, dass sie von dort wieder in die gebundenen Quellwerte konvertiert. Es wurde nicht entwickelt, um Ihnen zu ermöglichen, einen Quellwert basierend auf einem anderen Quellwert und dem Zielwert zu aktualisieren.

Es gibt eine Reihe von Möglichkeiten, um diese Einschränkung, aber keine, die ich kenne, sind sehr elegant.

Eine Option verwendet das Ansichtsmodell genau so, wie ich oben gezeigt habe. Der Trick besteht darin, dass Sie über ConverterParameter einen Verweis auf ComboBox mit der gebundenen Text Eigenschaft übergeben müssen, so dass die ConvertBack() Methode den aktuell ausgewählten Wert verwenden kann (Sie können den aktuell ausgewählten Wert selbst nicht als ConverterParamater Wert übergeben , weil ConverterParameter keine Abhängigkeitseigenschaft ist und daher nicht das Ziel einer Eigenschaftenbindung sein kann).

diese Weise getan, könnte man einen Konverter haben, die wie folgt aussieht:

class TimeConverter : IMultiValueConverter 
{ 
    public string Format { get; set; } 

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     DateTime utc = (DateTime)values[0]; 
     TimeZoneInfo tzi = (TimeZoneInfo)values[1]; 

     return tzi != null ? TimeZoneInfo.ConvertTime(utc, tzi).ToString(Format) : Binding.DoNothing; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     string timeText = (string)value; 
     DateTime time; 

     if (!DateTime.TryParseExact(timeText, Format, null, DateTimeStyles.None, out time)) 
     { 
      return new object[] { Binding.DoNothing, Binding.DoNothing }; 
     } 

     ComboBox comboBox = (ComboBox)parameter; 
     TimeZoneInfo tzi = (TimeZoneInfo)comboBox.SelectedValue; 

     return new object[] { TimeZoneInfo.ConvertTime(time, tzi, TimeZoneInfo.Utc), Binding.DoNothing }; 
    } 
} 

Und XAML, die wie folgt aussieht:

<Window x:Class="TestSO38517212BindTimeZoneAndTime.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:p="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:s="clr-namespace:System;assembly=mscorlib" 
     xmlns:l="clr-namespace:TestSO38517212BindTimeZoneAndTime" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.DataContext> 
    <l:ViewModel/> 
    </Window.DataContext> 

    <Window.Resources> 
    <ObjectDataProvider x:Key="timezone" 
         ObjectType="{x:Type s:TimeZoneInfo}" 
         MethodName="GetSystemTimeZones"> 
    </ObjectDataProvider> 
    <l:TimeConverter x:Key="timeConverter" Format="HH:mm:ss dd MMM yy"/> 
    <p:Style TargetType="ComboBox"> 
     <Setter Property="Width" Value="200"/> 
    </p:Style> 
    <p:Style TargetType="TextBox"> 
     <Setter Property="Width" Value="120"/> 
    </p:Style> 
    </Window.Resources> 

    <StackPanel> 
    <TextBlock Text="{Binding Time}"/> 
    <StackPanel Orientation="Horizontal"> 
     <ComboBox x:Name="comboBox1" ItemsSource="{Binding Source={StaticResource timezone}}" SelectedValue="{Binding TimeZone1}"/> 
     <TextBox> 
     <TextBox.Text> 
      <MultiBinding Converter="{StaticResource timeConverter}" 
         ConverterParameter="{x:Reference Name=comboBox1}" 
         UpdateSourceTrigger="PropertyChanged"> 
      <Binding Path="Time"/> 
      <Binding Path="SelectedValue" ElementName="comboBox1"/> 
      </MultiBinding> 
     </TextBox.Text> 
     </TextBox> 
    </StackPanel> 
    <StackPanel Orientation="Horizontal"> 
     <ComboBox x:Name="comboBox2" ItemsSource="{Binding Source={StaticResource timezone}}" SelectedValue="{Binding TimeZone2}"/> 
     <TextBox> 
     <TextBox.Text> 
      <MultiBinding Converter="{StaticResource timeConverter}" 
         ConverterParameter="{x:Reference Name=comboBox2}" 
         UpdateSourceTrigger="PropertyChanged"> 
      <Binding Path="Time"/> 
      <Binding Path="SelectedValue" ElementName="comboBox2"/> 
      </MultiBinding> 
     </TextBox.Text> 
     </TextBox> 
    </StackPanel> 
    <StackPanel Orientation="Horizontal"> 
     <ComboBox x:Name="comboBox3" ItemsSource="{Binding Source={StaticResource timezone}}" SelectedValue="{Binding TimeZone3}"/> 
     <TextBox> 
     <TextBox.Text> 
      <MultiBinding Converter="{StaticResource timeConverter}" 
         ConverterParameter="{x:Reference Name=comboBox3}" 
         UpdateSourceTrigger="PropertyChanged"> 
      <Binding Path="Time"/> 
      <Binding Path="SelectedValue" ElementName="comboBox3"/> 
      </MultiBinding> 
     </TextBox.Text> 
     </TextBox> 
    </StackPanel> 
    </StackPanel>  
</Window> 

zur Laufzeit Dies funktioniert gut. Sie erhalten jedoch aufgrund der Verwendung von {x:Reference ...} in den ConverterParameter Zuordnungen die Entwurfszeit _ "Objektreferenz nicht auf eine Instanz eines Objekts festgelegt".Für einige ist das eine kleine Unannehmlichkeit, aber ich finde es sehr ärgerlich und bin bereit, eine Menge Aufwand zu unternehmen, um es zu vermeiden. :)

So, hier ist ein völlig anderer Ansatz, der den Konverter ganz verzichtet und setzt die gesamte Logik in dem View-Modell selbst:

class ViewModel : INotifyPropertyChanged 
{ 
    private string _ktimeFormat = "HH:mm:ss dd MMM yy"; 

    // The actual time. Similar to the "timeAll" field you have in the code now 
    // Should be kept in UTC 
    private DateTime _time = DateTime.UtcNow; 

    // The three selected TimeZoneInfo values for the combo boxes 
    private TimeZoneInfo _timeZone1 = TimeZoneInfo.Utc; 
    private TimeZoneInfo _timeZone2 = TimeZoneInfo.Utc; 
    private TimeZoneInfo _timeZone3 = TimeZoneInfo.Utc; 

    // The text to display for each local time 
    private string _localTime1; 
    private string _localTime2; 
    private string _localTime3; 

    public ViewModel() 
    { 
     _localTime1 = _localTime2 = _localTime3 = _time.ToString(_ktimeFormat); 
    } 

    public DateTime Time 
    { 
     get { return _time; } 
     set { UpdateValue(ref _time, value); } 
    } 

    public TimeZoneInfo TimeZone1 
    { 
     get { return _timeZone1; } 
     set { UpdateValue(ref _timeZone1, value); } 
    } 

    public TimeZoneInfo TimeZone2 
    { 
     get { return _timeZone2; } 
     set { UpdateValue(ref _timeZone2, value); } 
    } 

    public TimeZoneInfo TimeZone3 
    { 
     get { return _timeZone3; } 
     set { UpdateValue(ref _timeZone3, value); } 
    } 

    public string LocalTime1 
    { 
     get { return _localTime1; } 
     set { UpdateValue(ref _localTime1, value); } 
    } 

    public string LocalTime2 
    { 
     get { return _localTime2; } 
     set { UpdateValue(ref _localTime2, value); } 
    } 

    public string LocalTime3 
    { 
     get { return _localTime3; } 
     set { UpdateValue(ref _localTime3, value); } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void UpdateValue<T>(ref T field, T value, [CallerMemberName] string propertyName = null) 
    { 
     if (!object.Equals(field, value)) 
     { 
      field = value; 
      OnPropertyChanged(propertyName); 
     } 
    } 

    private void OnPropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 

     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 

     switch (propertyName) 
     { 
     case "TimeZone1": 
      LocalTime1 = Convert(TimeZone1); 
      break; 
     case "TimeZone2": 
      LocalTime2 = Convert(TimeZone2); 
      break; 
     case "TimeZone3": 
      LocalTime3 = Convert(TimeZone3); 
      break; 
     case "LocalTime1": 
      TryUpdateTime(LocalTime1, TimeZone1); 
      break; 
     case "LocalTime2": 
      TryUpdateTime(LocalTime2, TimeZone2); 
      break; 
     case "LocalTime3": 
      TryUpdateTime(LocalTime3, TimeZone3); 
      break; 
     case "Time": 
      LocalTime1 = Convert(TimeZone1); 
      LocalTime2 = Convert(TimeZone2); 
      LocalTime3 = Convert(TimeZone3); 
      break; 
     } 
    } 

    private void TryUpdateTime(string timeText, TimeZoneInfo timeZone) 
    { 
     DateTime time; 

     if (DateTime.TryParseExact(timeText, _ktimeFormat, null, DateTimeStyles.None, out time)) 
     { 
      Time = TimeZoneInfo.ConvertTime(time, timeZone, TimeZoneInfo.Utc); 
     } 
    } 

    private string Convert(TimeZoneInfo timeZone) 
    { 
     return TimeZoneInfo.ConvertTime(Time, timeZone).ToString(_ktimeFormat); 
    } 
} 

Diese Version des View-Modells enthält die formatierten Textwerte. Anstatt einen Konverter zum Formatieren zu verwenden, wird hier alles als Reaktion auf Eigenschaftsänderungsbenachrichtigungen ausgeführt, die vom Ansichtsmodell selbst ausgelöst werden.

In dieser Version wird das Ansichtsmodell viel komplizierter. Aber es ist alles sehr einfach und leicht zu verstehen. Und die XAML windet sich viel einfacher bis:

<Window x:Class="TestSO38517212BindTimeZoneAndTime.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:p="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:s="clr-namespace:System;assembly=mscorlib" 
     xmlns:l="clr-namespace:TestSO38517212BindTimeZoneAndTime" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.DataContext> 
    <l:ViewModel/> 
    </Window.DataContext> 

    <Window.Resources> 
    <ObjectDataProvider x:Key="timezone" 
         ObjectType="{x:Type s:TimeZoneInfo}" 
         MethodName="GetSystemTimeZones"> 
    </ObjectDataProvider> 
    <p:Style TargetType="ComboBox"> 
     <Setter Property="Width" Value="200"/> 
    </p:Style> 
    <p:Style TargetType="TextBox"> 
     <Setter Property="Width" Value="120"/> 
    </p:Style> 
    </Window.Resources> 

    <StackPanel> 
    <TextBlock Text="{Binding Time}"/>   
    <StackPanel Orientation="Horizontal"> 
     <ComboBox x:Name="comboBox1" ItemsSource="{Binding Source={StaticResource timezone}}" SelectedValue="{Binding TimeZone1}"/> 
     <TextBox Text="{Binding LocalTime1, UpdateSourceTrigger=PropertyChanged}"/> 
    </StackPanel> 
    <StackPanel Orientation="Horizontal"> 
     <ComboBox x:Name="comboBox2" ItemsSource="{Binding Source={StaticResource timezone}}" SelectedValue="{Binding TimeZone2}"/> 
     <TextBox Text="{Binding LocalTime2, UpdateSourceTrigger=PropertyChanged}"/> 
    </StackPanel> 
    <StackPanel Orientation="Horizontal"> 
     <ComboBox x:Name="comboBox3" ItemsSource="{Binding Source={StaticResource timezone}}" SelectedValue="{Binding TimeZone3}"/> 
     <TextBox Text="{Binding LocalTime3, UpdateSourceTrigger=PropertyChanged}"/> 
    </StackPanel> 
    </StackPanel>  
</Window> 

Entweder sollten diese direkt auf das Problem eingehen Sie sind gefragt, dh so dass Änderungen in einer von mehreren Werten, die von einem einzelnen Wert abgeleitet werden umgewandelt werden vermehrt zurück zu den anderen Werten. Aber wenn keiner von beiden zu Ihnen passt, haben Sie eine Reihe anderer Optionen.

Einer der offensichtlichsten ist, einfach abonnieren Sie die entsprechenden Eigenschaft geändert Ereignisse in jedem Steuerelement und dann explizit kopieren Sie zurück zu den anderen Steuerelementen die gewünschten Werte. IMHO das wäre sehr unelegant, aber es würde nicht unbedingt die Verwendung des View-Model-Paradigma erfordern, und so könnte argumentiert werden, dass würde mehr mit Ihrem ursprünglichen Beispiel übereinstimmen.

Ein anderer Ansatz wäre, Ihre Konverter viel mehr Schwergewicht zu machen, indem es DependencyObject erben machen, so dass es eine Abhängigkeitseigenschaft haben kann als das Ziel des Zeitzonenwertes gebunden. Sie müssten immer noch die IMultiBindingConverter-Methode verwenden, um die Ziel-Text-Eigenschaft festzulegen, aber dies würde einen weniger hacky Weg ermöglichen, um sicherzustellen, dass die Zeitzoneninformationen in ConvertBack() verfügbar sind.

Sie können ein Beispiel für diesen Ansatz in this answer to Get the Source value in ConvertBack() method for IValueConverter implementation in WPF binding sehen. Beachten Sie, dass bei dieser Vorgehensweise jede Bindung eine eigene Instanz des Konverters benötigt. Keine Freigabe als Ressource.

+0

Ich weiß, ich soll hier nicht danken, aber Ihr Code hat mir viel beigebracht !! Ich lerne WPF als ein Interesse und es war ziemlich schwierig, war so kurz davor aufzugeben. Vielen Dank für die geduldige Erklärung und das Teilen einiger cooler Programmiermethoden. –

+1

Sie sind herzlich willkommen. Ich stimme zu, die Lernkurve auf WPF ist steil. Es ist nicht von der Tatsache, dass die WPF-API selbst bietet mehrere Möglichkeiten, um das gleiche zu tun, und es ist nicht immer klar, was der "richtige" Weg ist nicht hilfreich. Es gibt eine Menge Komplexität und versteckte Regeln, die schwer zu verstehen sind. Ich bin froh, dass das oben genannte Ihnen geholfen hat, zumindest einige davon zu überwinden. FWIW, obwohl ich nicht sicher bin, ob ich mich als WPF-Experte qualifiziere, bin ich an dem vorbeigekommen, was ich für den steilsten Teil der Lernkurve halte. Ich ermutige Sie dazu, es weiter zu versuchen, da ich festgestellt habe, dass, sobald Sie WPF verstehen, es tatsächlich einige sehr nette Funktionen bietet. –