繁体   English   中英

WPF使用数据绑定显示日期选择器的年龄

[英]WPF Display age from datepicker using data binding

我有一个带datepickerlabel的小window 目的是显示已选择出生日期的人的年龄。 我为此使用MVVM light,我需要使用ViewModel.cs 我可以只使用XAML吗? 如果没有,如何实现?

我的ViewModel:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GalaSoft.MvvmLight;
using System.Windows.Controls;

namespace zh1_beteges
{
    public class PatientVM : ViewModelBase
    {
        Patient b = null;

        int age;
        DatePicker DP;
        public int Age
        {
            get { return age; }
            set { Set(ref age, value); }
        }
        public Patient B
        {
            get
            {
                return b;
            }
            set { Set(ref b, value); }
        }
        public PatientVM(DatePicker DP)
        {
            this.DP = DP;
        }
        public PatientVM(Patient b, DatePicker DP)
        {
            this.B = b;
            this.DP = DP;
            age = DateTime.Today.Year - b.DateOfBirth.Year;
        }


    }
}

和我的XAML:

<Window x:Class="zh1_beteges.BetegAdatai"
    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:zh1_beteges"
    mc:Ignorable="d"
    Title="BetegAdatai" Height="314.894" Width="512.766"
    WindowStartupLocation="CenterScreen"
    >
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="0.7*"/>
        <ColumnDefinition Width="0.7*"/>
    </Grid.ColumnDefinitions>
    <Label Content="Patient name:" HorizontalAlignment="Left" VerticalAlignment="Center"
           FontSize="14" Margin="10,0,10,0" Grid.Row="0" Grid.Column="0">
    </Label>
    <Label Content="PlaceOfBirth: " HorizontalAlignment="Left" VerticalAlignment="Center"
           FontSize="14" Margin="10,0,10,0" Grid.Row="1" Grid.Column="0">
    </Label>
    <Label Content="date of birth:" HorizontalAlignment="Left" VerticalAlignment="Center"
           FontSize="14" Margin="10,0,10,0" Grid.Row="2" Grid.Column="0">
    </Label>
    <Label Content="TAJ:" HorizontalAlignment="Left" VerticalAlignment="Center"
           FontSize="14" Margin="10,0,10,0" Grid.Row="3" Grid.Column="0">
    </Label>
    <Label Content="Age:" HorizontalAlignment="Left" VerticalAlignment="Center"
           FontSize="14" Margin="10,0,10,0" Grid.Row="2" Grid.Column="2">
    </Label>
    <Label Content="{Binding Path=Age}" HorizontalAlignment="Left" VerticalAlignment="Center"
           FontSize="14" Margin="10,0,10,0" Grid.Row="2" Grid.Column="3">
    </Label>
    <Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
            Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="4" Margin="170,5,170,5"
            Content="OK" FontSize="14">
    </Button>
    <DatePicker x:Name="DP" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Center"
                VerticalAlignment="Center" DisplayDateStart="2016/01/01"
                SelectedDate="{Binding Path=B.SzuletesiDatum}">
    </DatePicker>
    <TextBox Margin="10,5,10,5" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="3"
             Text="{Binding Path=B.Name}" VerticalContentAlignment="Center" >
    </TextBox>
    <TextBox Margin="10,5,10,5" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3"
             Text="{Binding Path=B.PlaceOfBirth}" VerticalContentAlignment="Center" >
    </TextBox>
    <TextBox Margin="10,5,10,5" Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="3"
             Text="{Binding Path=B.TAJ}"  VerticalContentAlignment="Center">
    </TextBox>
</Grid>

和我的Xaml.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace zh1_beteges
{
    /// <summary>
    /// Interaction logic for PatientData.xaml
    /// </summary>
    public partial class PatientData : Window
    {
        public PatientVM bvm;
        public PatientData()
        {
            InitializeComponent();
            bvm = new PatientVM(DP);
            this.DataContext = bvm;
        }
        public PatientData(Patient b)
        {
            InitializeComponent();
            bvm = new PatientVM(b,DP);
            this.DataContext = bvm;
        }
    }
}

是的,您可以使用自定义转换器来执行此操作。 自定义转换器使您可以将数据绑定到与该数据转换的另一个值。 在您的情况下,您需要一个将所选日期转换为经过该日期的时间的转换器。

您应该创建一个这样的类:

public class DatetimeToPassedDateConverter : IValueConverter,MarkupExtension
{
    public object Convert(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        if(value is DateTime)
            return DateTime.Now-(DateTime)value;
        else
            return null;
    }

    public object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        // Convert back which is not required in your case
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}

然后像这样在您的XAML中使用它:

<Label Content="{Binding ElementName=DP,Path=SelectedDate,Converter={namespace:DatetimeToPassedDateConverter}}" HorizontalAlignment="Left" VerticalAlignment="Center"
       FontSize="14" Margin="10,0,10,0" Grid.Row="2" Grid.Column="3">
</Label>

有关自定义转换器的更多信息,请参见本文

您可以在PatientVM创建名为SelectedDate属性:

private DateTime? selectedDate;
public DateTime? SelectedDate
{
    get
    {
        return selectedDate;
    }
    set
    {
        selectedDate = value;
        RaisePropertyChanged("SelectedDate");
        DateSelectionChangedExecute();
    }
}

然后在DateSelectionChangedExecute计算Age (例如,应改进此方法以防止年龄过大):

private void DateSelectionChangedExecute()
{
     if (SelectedDate != null && SelectedDate.Value != null)
         Age = DateTime.Now.Year - SelectedDate.Value.Year;
}

并将SelectedDate绑定到xaml中的DatePicker

<DatePicker x:Name="DP" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Center" 
                VerticalAlignment="Center" DisplayDateStart="2016/01/01"
                SelectedDate="{Binding SelectedDate}">
</DatePicker>

因此,每次更改SelectedDate时,都会计算Age

暂无
暂无

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

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