WPF使用数据绑定显示来自datepicker的年龄

时间:2016-11-05 10:08:56

标签: c# wpf xaml mvvm datepicker

我有一个window datepickerlabel。目标是显示选择出生日期的人的年龄。我正在使用MVVM灯,我需要使用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;
        }
    }
}

2 个答案:

答案 0 :(得分:1)

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

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

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>

有关自定义转换器的详细信息,请参阅this article

答案 1 :(得分:1)

您可以在名为[gridOptions]="gridOptions" [columnDefs]="columnDefs" [showToolPanel]="showToolPanel" [rowData]="rowData" enableColResize debug rowHeight="30" rowSelection="multiple" rowModelType="pagination" paginationPageSize = "15" 的{​​{1}}内创建属性:

PatientVM

然后在SelectedDate中计算private DateTime? selectedDate; public DateTime? SelectedDate { get { return selectedDate; } set { selectedDate = value; RaisePropertyChanged("SelectedDate"); DateSelectionChangedExecute(); } } (例如,应该改进此方法以防止出现负面年龄):

DateSelectionChangedExecute

Age绑定到xaml中的private void DateSelectionChangedExecute() { if (SelectedDate != null && SelectedDate.Value != null) Age = DateTime.Now.Year - SelectedDate.Value.Year; }

SelectedDate

感谢每次更改DatePicker时,都会计算<DatePicker x:Name="DP" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" DisplayDateStart="2016/01/01" SelectedDate="{Binding SelectedDate}"> </DatePicker>