2016-06-15 91 views
2

我使用的是下面的填充我的組合框的時區信息選擇時區數據綁定,顯示時間,文本框:使用基於組合框

MainWindow.xaml.cs

private void Window_Loaded(object sender, RoutedEventArgs e) 
{ 
    ReadOnlyCollection<TimeZoneInfo> TimeZones = TimeZoneInfo.GetSystemTimeZones(); 
    this.DataContext = TimeZones; 
    cmb_TZ.SelectedIndex = 1; 
} 

的下面是從XAML:

<ComboBox x:Name="cmb_TZ" ItemsSource="{Binding}" Grid.Row="0" Grid.Column="2" Height="28.5" Margin="10,65.375,30.945,0" VerticalAlignment="Top" d:LayoutOverrides="LeftMargin, RightMargin, TopMargin, BottomMargin" SelectionChanged="ComboBox_Selection"/> 

我還可以通過使用此代碼顯示在文本相應的值:

private void ComboBox_Selection(object Sender, SelectionChangedEventArgs e) 
{ 
    var cmbBox = Sender as ComboBox; 
    DateTime currTime = DateTime.UtcNow; 
    TimeZoneInfo tst = (TimeZoneInfo)cmbBox.SelectedItem; 
    txt_Time.Text = TimeZoneInfo.ConvertTime(currTime, TimeZoneInfo.Utc, tst).ToString("HH:mm:ss dd MMM yy"); 
} 

其中txt_Time是我的文本框中。它的XAML代碼:

<TextBox x:Name="txt_Time" Grid.Row="0" Grid.Column="1" Height="28.5" Margin="26.148,65.375,28.13,0" TextWrapping="Wrap" VerticalAlignment="Top" d:LayoutOverrides="LeftMargin, RightMargin, TopMargin, BottomMargin"/> 

我的問題是:

有沒有辦法做到這一點使用數據綁定? 我能夠使用上面顯示的直接方法來做到這一點。但我想知道這個計算是否可以通過數據綁定完成?

我是新來的C#/ WPF和我試圖創建一個簡單的類,並且還使用INotifyPropertyChanged的,並指它在主窗口構造函數的類,但我不能讓即使填充組合框。

我真的很想理解和使用C#的數據綁定魔法。

+0

你想綁定Combobox中的所有值嗎? – Balaji

+0

組合框將有一個時區列表,我希望能夠在文本框中顯示相應的時間,具體取決於我在CB中選擇的時區。 –

+1

「我真的很想理解和使用C#的數據綁定魔法。」如果你真的想這樣做,你應該去找一個沒有任何事件處理程序代碼的解決方案,如其他答案所示。 – Clemens

回答

1

在標準的MVVM ap建議您創建一個包含兩個屬性的視圖模型類,一個用於所有TimeZoneInfos的只讀集合,另一個用於當前選定的TimeZone。

public class ViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public ReadOnlyCollection<TimeZoneInfo> TimeZones { get; } 
     = TimeZoneInfo.GetSystemTimeZones(); 

    private TimeZoneInfo selectedTimeZone = TimeZoneInfo.Local; 

    public TimeZoneInfo SelectedTimeZone 
    { 
     get { return selectedTimeZone; } 
     set 
     { 
      selectedTimeZone = value; 
      PropertyChanged?.Invoke(this, 
       new PropertyChangedEventArgs("SelectedTimeZone")); 
     } 
    } 
} 

您可以在窗口的DataContext設置爲視圖模型的實例,並綁定組合框和文本框的屬性,如顯示在此XAML:

<Window ...> 
    <Window.DataContext> 
     <local:ViewModel/> 
    </Window.DataContext> 
    <Window.Resources> 
     <local:TimeZoneConverter x:Key="TimeZoneConverter" /> 
    </Window.Resources> 
    <StackPanel> 
     <ComboBox ItemsSource="{Binding TimeZones}" 
        SelectedItem="{Binding SelectedTimeZone}" /> 
     <TextBox Text="{Binding SelectedTimeZone, 
         Converter={StaticResource TimeZoneConverter}}"/> 
    </StackPanel> 
</Window> 

在裝訂Text屬性用途a這樣的轉換器:

public class TimeZoneConverter : IValueConverter 
{ 
    public object Convert(
     object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return value == null ? string.Empty : TimeZoneInfo 
      .ConvertTime(DateTime.UtcNow, 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(); 
    } 
} 
1

在你ComboBox,結合其ItemSourceReadOnlyCollection

<ComboBox x:Name="cmb_TZ" ItemsSource="{Binding TimeZoneList}" Grid.Row="0" Grid.Column="2" Height="28.5" Margin="10,65.375,30.945,0" VerticalAlignment="Top" d:LayoutOverrides="LeftMargin, RightMargin, TopMargin, BottomMargin" SelectionChanged="ComboBox_Selection"/> 

現在要顯示綁定到財產的時候,

<TextBox x:Name="txt_Time" Text="{Binding TimeZome}" Grid.Row="0" Grid.Column="1" Height="28.5" Margin="26.148,65.375,28.13,0" TextWrapping="Wrap" VerticalAlignment="Top" d:LayoutOverrides="LeftMargin, RightMargin, TopMargin, BottomMargin"/> 

的相應的CS文件現在,

public partial class MainWindow : Window, INotifyPropertyChanged 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      this.DataContext = this; 
     } 


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

     private void ComboBox_Selection(object sender, SelectionChangedEventArgs e) 
     { 
      var cmbBox = sender as ComboBox; 
      DateTime currTime = DateTime.UtcNow; 
      TimeZoneInfo tst = (TimeZoneInfo)cmbBox.SelectedItem; 
      TimeZome = TimeZoneInfo.ConvertTime(currTime, TimeZoneInfo.Utc, tst).ToString("HH:mm:ss dd MMM yy"); 
     } 

     private string _TimeZome; 
     public string TimeZome 
     { 
      get { return _TimeZome; } 
      set 
      { 
       if (value == _TimeZome) 
        return; 

       _TimeZome = value; 
       this.OnPropertyChanged("TimeZome"); 
      } 
     } 
     private ReadOnlyCollection<TimeZoneInfo> _TimeZoneList; 
     public ReadOnlyCollection<TimeZoneInfo> TimeZoneList 
     { 
      get { return _TimeZoneList; } 
      set 
      { 
       if (value == _TimeZoneList) 
        return; 

       _TimeZoneList = value; 
       this.OnPropertyChanged("TimeZoneList"); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     public void OnPropertyChanged(string propertyName) 
     { 
      PropertyChangedEventHandler handler = PropertyChanged; 
      if (handler != null) 
      { 
       handler(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 
1

使用ObjectDataProvider將簡化您的代碼。只是爲了這個問題,實際上你不需要在CS中編寫視圖模型。

<Window x:Class="WpfApplication2.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:src="clr-namespace:System;assembly=mscorlib" 
     xmlns:sys="clr-namespace:System;assembly=System.Core" 
     xmlns:local="clr-namespace:WpfApplication2" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <ObjectDataProvider x:Key="timezone" ObjectType="{x:Type sys:TimeZoneInfo}" MethodName="GetSystemTimeZones"></ObjectDataProvider> 
     <local:TimeZoneConverter x:Key="timezoneconverter"/> 
    </Window.Resources> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*"/> 
      <ColumnDefinition Width="*"/> 
     </Grid.ColumnDefinitions> 
     <ComboBox x:Name="cmb_TZ" ItemsSource="{Binding Source={StaticResource timezone}}" Height="30" /> 
     <TextBlock x:Name="txt_Time" Grid.Column="1" Text="{Binding ElementName=cmb_TZ, Path=SelectedValue, Converter={StaticResource timezoneconverter}}"/> 
    </Grid> 
</Window> 

而且還需要克萊門斯的轉換器。

public class TimeZoneConverter : IValueConverter 
{ 
    public object Convert(
     object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return value == null ? string.Empty : TimeZoneInfo 
      .ConvertTime(DateTime.UtcNow, 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(); 
    } 
}