C# - WPF自定义用户控件多次查看同一视图

时间:2018-05-18 16:37:30

标签: c# wpf caliburn.micro

我们在客户端规范下开发了一种日期捕获组件,这个组件必须在我们捕获日期的所有视图中使用,但是如果我们在同一个视图中多次放置这个组件,那么当我们在所有组件中的值发生变化时更新任何一个。

这是我的观点代码:

<UserControl x:Class="Mx.Gob.Biometrics.UniversalBiometric.Views.CalendarView"
         cal:Bind.Model="Mx.Gob.Biometrics.UniversalBiometric.ViewModels.CalendarViewModel" 
         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:Mx.Gob.Biometrics.UniversalBiometric.Views"
         xmlns:local1="clr-namespace:Mx.Gob.Biometrics.UniversalBiometric.Views.Controls"
         xmlns:Controls="http://metro.mahapps.com/winfx/xaml/controls"
         mc:Ignorable="d" 
         xmlns:cal="http://www.caliburnproject.org"
         d:DesignHeight="110" d:DesignWidth="300">
<Grid Background="White">
    <Grid.ColumnDefinitions>
        <ColumnDefinition ></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>

    <Border BorderBrush="{DynamicResource TextBoxBorderBrush}" BorderThickness="1" Margin="3,3,3,3">
        <AdornerDecorator>
            <Grid Grid.Column="0" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" >

                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="2*"></ColumnDefinition>
                    <ColumnDefinition Width="*"></ColumnDefinition>
                    <ColumnDefinition Width="2*"></ColumnDefinition>
                    <ColumnDefinition Width="*"></ColumnDefinition>
                    <ColumnDefinition Width="4*"></ColumnDefinition>
                </Grid.ColumnDefinitions>

                <Grid.RowDefinitions>
                    <RowDefinition></RowDefinition>
                    <RowDefinition></RowDefinition>
                </Grid.RowDefinitions>

                <local1:AutoFocusText x:Name="Day" Grid.Column="0"  Text="{Binding Day , ValidatesOnDataErrors=True}"  MaxLength="2"  BorderThickness="0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                <Label Margin =" 0,0,0,0" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="{DynamicResource TextBoxBorderBrush}">
                    <TextBlock Margin =" 0,0,0,0" Text="/"/>
                </Label>
                <local1:AutoFocusText x:Name="Month" Grid.Column="2" Text="{Binding Month,  ValidatesOnDataErrors=True}"  MaxLength="2" BorderThickness="0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                <Label Margin =" 0,0,0,0" Grid.Column="3" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="{DynamicResource TextBoxBorderBrush}">
                    <TextBlock  Margin =" 0,0,0,0" Text="/"/>
                </Label>
                <local1:AutoFocusText x:Name="Year" Grid.Column="4" Text="{Binding Year,  ValidatesOnDataErrors=True}"  MaxLength="4" BorderThickness="0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
            </Grid>
        </AdornerDecorator>
    </Border>
</Grid>

这是ViewModel的代码:

using Caliburn.Micro;
using Mx.Gob.Biometrics.UniversalBiometric.ViewModels.Interface;
using System;
namespace Mx.Gob.Biometrics.UniversalBiometric.ViewModels
{
public class CalendarViewModel : Screen, ICalendarViewModel
{
    private DateTime? date;
    public bool validate;
    public CalendarViewModel()
    {
        date = new DateTime();

        validate = false;
        this.NotifyOfPropertyChange(() => Day);
        this.NotifyOfPropertyChange(() => Month);
        this.NotifyOfPropertyChange(() => Year);
    }

    private const string DAY_MASK = "DD";
    private const string MONTH_MASK = "MM";
    private const string YEAR_MASK = "YYYY";


    public DateTime? Date
    {
        get
        {
            return date;
        }
        set
        {
            date = value;
            this.NotifyOfPropertyChange(() => Day);
            this.NotifyOfPropertyChange(() => Month);
            this.NotifyOfPropertyChange(() => Year);
            this.NotifyOfPropertyChange(() => Date);
        }
    }

    private void CrearFecha()
    {
        if (ValidateInformation())
        {
            date = new DateTime(year ?? default(int), month ?? default(int), day ?? default(int));
            day = date.Value.Day;
            month = date.Value.Month;
            year = date.Value.Year;
        }
        else
        {
            date = null;
            day = null;
            month = null;
            year = null;
        }
        this.NotifyOfPropertyChange(() => Day);
        this.NotifyOfPropertyChange(() => Month);
        this.NotifyOfPropertyChange(() => Year);
        this.NotifyOfPropertyChange(() => Date);


    }

    public bool ValidateInformation()
    {
        int maxDay;
        bool validate = false;
        if (IsMasked())
        {
            return false;
        }

        if (year < DateTime.MinValue.Year || year > DateTime.MaxValue.Year)
        {
            return false;
        }

        if (month < 1 || month > 12)
        {
            return false;
        }
        if (month == null || year == null)
        {
            maxDay = 30;
        }
        else
        {
            maxDay = DateTime.DaysInMonth(year ?? default(int), month ?? default(int));
        }

        if (day < 1 || day >= maxDay)
        {
            return false;
        }

        validate = true;
        return validate;
    }

    private Nullable<int> day;
    public string Day
    {
        get
        {
            return day != null ? day.ToString() : DAY_MASK;
        }
        set
        {
            int d;
            int.TryParse(value, out d);
            if (d > 0)
            {
                day = d;
            }
            else
            {
                day = null;
            }
            UpdateDate();
            this.NotifyOfPropertyChange(() => Day);
        }
    }
    private Nullable<int> month;

    public string Month
    {
        get
        {
            return month != null ? month.ToString() : MONTH_MASK;
        }
        set
        {
            int m;
            int.TryParse(value, out m);
            if (m > 0)
            {
                month = m;
            }
            else
            {
                month = null;
            }
            UpdateDate();
            this.NotifyOfPropertyChange(() => Month);
        }
    }
    private Nullable<int> year;

    public string Year
    {
        get
        {
            return year != null ? year.ToString() : YEAR_MASK;
        }
        set
        {
            int y;
            int.TryParse(value, out y);
            if (y > 0)
            {
                year = y;
            }
            else
            {
                year = null;
            }
            UpdateDate();
            this.NotifyOfPropertyChange(() => Year);
        }
    }

    public void UpdateDate()
    {
        if (!IsMasked())
        {
            CrearFecha();
        }
        else
        {
            Date = null;
        }
    }


    public bool Validate
    {
        get { return validate; }
        set { validate = value; }
    }

    public string Error
    {
        get
        {
            return this["Day"] + this["Month"] + this["Year"];
        }

    }

    public string this[string columnName]
    {
        get
        {
            switch (columnName)
            {
                case "Day":
                case "Month":
                case "Year":
                    if (ValidateInformation())
                    {
                        validate = false;
                        return string.Empty;
                    }
                    else
                    {
                        validate = true;
                        return "Fecha Invalida";
                    }

            }
            validate = false;
            return string.Empty;

        }
    }

    private bool IsMasked()
    {
        return DAY_MASK.Equals(Day) || MONTH_MASK.Equals(Month) || YEAR_MASK.Equals(Year);
    }

}
}

这是界面代码:

using System;

namespace Mx.Gob.Biometrics.UniversalBiometric.ViewModels.Interface

{
public interface ICalendarViewModel
{
    bool Validate
    {
        get;
        set;
    }

    DateTime? Date
    {
        get;
    }
}
}

这里是我们使用这个组件的视图的代码:

<UserControl x:Class="Mx.Gob.Biometrics.UniversalBiometric.Views.LogQueryView"
         cal:Bind.Model="Mx.Gob.Biometrics.UniversalBiometric.ViewModels.LogQueryViewModel" 
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:Mx.Gob.Biometrics.UniversalBiometric.Views"
         xmlns:cal="http://www.caliburnproject.org"
        >
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
    <Label Grid.Column="1" Grid.Row="0" Content="Start Date"></Label>
    <Label Grid.Column="1" Grid.Row="1" Content="End Date"></Label>
    <local:CalendarView x:Uid="DateStart" Grid.Column="2" Grid.Row="0" x:Name="DateStartView"/>
    <local:CalendarView x:Uid="DateEnd" Grid.Column="2" Grid.Row="1" x:Name="DateEndView"/>
</Grid>

这是视图模型:

using Caliburn.Micro;
using Mx.Gob.Biometrics.UniversalBiometric.ViewModels.Interface;

namespace Mx.Gob.Biometrics.UniversalBiometric.ViewModels

{
public class LogQueryViewModel : Screen, ILogQueryViewModel
{
    private ICalendarViewModel dateStartView;
    private ICalendarViewModel dateEndView;

    public LogQueryViewModel()
    {
        dateStartView = new CalendarViewModel();
        dateEndView = new CalendarViewModel();
    }

    public ICalendarViewModel DateStartView
    {
        get
        {
            return dateStartView;
        }
        set
        {
            dateStartView = value;
            NotifyOfPropertyChange(() => DateStartView);
        }

    }
    public ICalendarViewModel DateEndView
    {
        get
        {
            return dateEndView;
        }
        set
        {
            dateEndView = value;
            NotifyOfPropertyChange(() => DateEndView);
        }

    }

}

}

0 个答案:

没有答案