c# - WPF将用户控件属性绑定到主窗口
问题描述
我正在制作自定义日期和时间用户控件,但遇到了让绑定工作的问题。我认为一切都在用户控制方面工作?但不是在窗边。当您单击按钮时,我的小测试设置应该使用控件上选择的日期和时间来更新窗口的标题。目前它没有更新新的日期。如果我在 's setter 上设置断点,myDate
当我更改日期时它不会被调用。如何正确绑定到用户控件?
用户控件 xaml
<UserControl x:Class="DateTimeCntrl.DateTimeControl"
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"
xmlns:local="clr-namespace:DateTimeCntrl"
mc:Ignorable="d"
d:DesignHeight="32" d:DesignWidth="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ComboBox Grid.Column="0"
x:Name="cbMonth"
SelectionChanged="cb_SelectionChanged"
DisplayMemberPath="Key"
SelectedValuePath="Value"/>
<ComboBox Grid.Column="1"
x:Name="cbDay"
SelectionChanged="cb_SelectionChanged"
DisplayMemberPath="Key"
SelectedValuePath="Value"/>
<ComboBox Grid.Column="2"
x:Name="cbYear"
SelectionChanged="cb_SelectionChanged"
DisplayMemberPath="Key"
SelectedValuePath="Value"/>
<ComboBox Grid.Column="3"
x:Name="cbHour"
SelectionChanged="cb_SelectionChanged"
DisplayMemberPath="Key"
SelectedValuePath="Value"/>
<ComboBox Grid.Column="4"
x:Name="cbMinute"
SelectionChanged="cb_SelectionChanged"
DisplayMemberPath="Key"
SelectedValuePath="Value"/>
<ComboBox Grid.Column="5"
x:Name="cbAmPm"
SelectionChanged="cb_SelectionChanged"
DisplayMemberPath="Key"
SelectedValuePath="Value"/>
</Grid>
</UserControl>
后面的用户控制代码
public partial class DateTimeControl : UserControl {
public static readonly DependencyProperty SetDateProperty = DependencyProperty.Register("Date", typeof(DateTime), typeof(DateTimeControl), new PropertyMetadata(DateTime.Now, new PropertyChangedCallback(OnDateChanged)));
public DateTime Date {
get { return (DateTime)GetValue(SetDateProperty); }
set { SetValue(SetDateProperty, value); }
}
public int Month { get { return cbMonth.SelectedValue == null ? 1 : (int)cbMonth.SelectedValue; } }
public int Day { get { return cbDay.SelectedValue == null ? 1 : (int)cbDay.SelectedValue; } }
public int Year { get { return cbYear.SelectedValue == null ? 1999 : (int)cbYear.SelectedValue; } }
public int Hour { get { return cbHour.SelectedValue == null ? 1 : (int)cbHour.SelectedValue; } }
public int Minute { get { return cbMinute.SelectedValue == null ? 1 : (int)cbMinute.SelectedValue; } }
public int AmPm { get { return cbAmPm.SelectedValue == null ? 1 : (int)cbAmPm.SelectedValue; } }
private static void OnDateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
}
private void OnDateChanged(DependencyPropertyChangedEventArgs e) {
DateTime now = (DateTime)e.NewValue;
cbMonth.SelectedValue = now.Month;
cbDay.SelectedValue = now.Day;
cbYear.SelectedValue = now.Year;
cbHour.SelectedValue = now.Hour > 12 ? now.Hour - 12 : now.Hour;
cbMinute.SelectedValue = now.Minute;
cbAmPm.SelectedValue = now.Hour > 12 ? 2 : 1;
}
public DateTimeControl() {
InitializeComponent();
//DataContext = this;
DateTime now = DateTime.Now;
//Months
for(int i = 1; i < 13; i++) {
string m = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(i);
cbMonth.Items.Add(new KeyValuePair<string, int>(m, i));
}
cbMonth.SelectedValue = now.Month;
//Days
for(int i = 1; i < 32; i++) {
string d;
if (i < 10)
d = "0" + i.ToString();
else
d = i.ToString();
cbDay.Items.Add(new KeyValuePair<string, int>(d, i));
}
cbDay.SelectedValue = now.Day;
//Years
for(int i = DateTime.Now.Year; i > DateTime.Now.Year - 10; i--) {
cbYear.Items.Add(new KeyValuePair<string, int>(i.ToString(), i));
}
cbYear.SelectedValue = now.Year;
//Hours
for(int i = 1; i < 13; i++) {
cbHour.Items.Add(new KeyValuePair<string, int>(i.ToString(), i));
}
cbHour.SelectedValue = now.Hour > 12 ? now.Hour - 12 : now.Hour;
//Minutes
for (int i = 0; i < 60; i++) {
string m;
if (i < 10)
m = "0" + i.ToString();
else
m = i.ToString();
cbMinute.Items.Add(new KeyValuePair<string, int>(m, i));
}
cbMinute.SelectedValue = now.Minute;
//AM PM
cbAmPm.Items.Add(new KeyValuePair<string, int>("Am", 1));
cbAmPm.Items.Add(new KeyValuePair<string, int>("Pm", 2));
cbAmPm.SelectedValue = now.Hour > 12 ? 2 : 1;
}
private void updateTime() {
Date = new DateTime(Year, Month, Day, Hour + AmPm == 2 ? 12 : 0, Minute, 0);
}
private void cb_SelectionChanged(object sender, SelectionChangedEventArgs e) {
updateTime();
}
}
主窗口 xaml
<Window x:Class="DateTimeCntrl.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:local="clr-namespace:DateTimeCntrl"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<local:DateTimeControl Date="{Binding myDate}"/>
<Button Grid.Row="1" Click="Button_Click">click me</Button>
</Grid>
</Window>
主窗口 xaml
public partial class MainWindow : Window {
MainViewModel viewmodel;
public MainWindow() {
InitializeComponent();
DataContext = viewmodel = new MainViewModel();
}
private void Button_Click(object sender, RoutedEventArgs e) {
Title = viewmodel.myDate.ToString();
}
}
主窗口视图模型
public class MainViewModel : BaseViewModel {
private DateTime mydate;
public DateTime myDate {
get {
return mydate;
}
set {
mydate = value;
RaisePropertyChanged("myDate");
}
}
}
解决方案
Use the TwoWay binding mode Date="{Binding myDate, Mode=TwoWay}"
in Window xaml
while binding to dependency property.
<local:DateTimeControl Date="{Binding myDate, Mode=TwoWay}"/>
推荐阅读
- angular - Angular5 - 使用 HttpClient 轮询 JSON
- javascript - js 承诺解决在模拟函数中不起作用
- php - php数组用键搜索
- python - 如何从队列中返回线程的第一个参数以及线程的返回?
- html - 在伪元素未显示之前
- python - 使用带有空格的 PySpark ORC 路径
- javascript - React 应用程序没有正确更新 this.state
- node.js - Angular 5 Firebase 数据库查询
- laravel - 如何正确地将每个答案存储在答案表中?(出现 SQLSTATE[23000] 错误)
- here-olp - 如何在本地运行 HERE Open Location Platform SDK 的示例?