简体   繁体   English

WPF 将用户控件属性绑定到主 Window

[英]WPF Binding Usercontrol Property to Main Window

I'm making a custom date and time usercontrol, but running into a problem getting the binding to work.我正在制作自定义日期和时间用户控件,但遇到了让绑定工作的问题。 I think everything is working on the usercontrol side?.我认为一切都在用户控制方面工作? But not on the window side.但不在 window 方面。 My little test setup should update the window's title with the date and time selected on the control when you click a button.当您单击按钮时,我的小测试设置应该使用控件上选择的日期和时间来更新窗口的标题。 Currently it's not updating the new date.目前它没有更新新的日期。 If I set a breakpoint on myDate 's setter it doesn't get called when I change the date.如果我在myDate的设置器上设置断点,则在更改日期时不会调用它。 How do I correctly bind to a usercontrol?如何正确绑定到用户控件?

Usercontrol xaml用户控制 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>

Usercontrol code behind后面的用户控制代码

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

Main Window xaml主营Window 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>

Main Window xaml主营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();
        }
    }

Main Window View Model主Window 查看Model

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.在绑定到依赖属性时,使用Window xaml中的 TwoWay 绑定模式Date="{Binding myDate, Mode=TwoWay}"

<local:DateTimeControl Date="{Binding myDate, Mode=TwoWay}"/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM