使用基于组合框

问题描述:

我使用的是下面的填充我的组合框的时区信息选择时区数据绑定,显示时间,文本框:使用基于组合框

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

在标准的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(); 
    } 
} 

在你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)); 
      } 
     } 
    } 

使用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(); 
    } 
}