使用基于组合框
问题描述:
我使用的是下面的填充我的组合框的时区信息选择时区数据绑定,显示时间,文本框:使用基于组合框
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#的数据绑定魔法。
答
在标准的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
,结合其ItemSource
到ReadOnlyCollection
,
<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();
}
}
你想绑定Combobox中的所有值吗? – Balaji
组合框将有一个时区列表,我希望能够在文本框中显示相应的时间,具体取决于我在CB中选择的时区。 –
“我真的很想理解和使用C#的数据绑定魔法。”如果你真的想这样做,你应该去找一个没有任何事件处理程序代码的解决方案,如其他答案所示。 – Clemens