DataGridTextColumn仅显示/编辑时间,日期绑定到父usercontrol的属性

时间:2013-05-29 16:18:07

标签: wpf binding

我在DataGrid内有一个UserControl。我希望DataGridTextColumn绑定到DateTime字段,仅显示时间。当用户输入时间时,日期部分(年,月,日)应取自AttendDate上的属性(UserControl)。

我的第一个想法是将用户控件的属性绑定到ConverterParameter

<DataGridTextColumn Header="From" 
    Binding="{Binding FromDate, Converter={StaticResource TimeConverter},ConverterParameter={Binding AttendDate,ElementName=UC}}"
/>

ConverterParameter没有约束力。然后我想用MultiBinding

来做这件事
<DataGridTextColumn Header="משעה" Binding="{Binding FromDate, Converter={StaticResource TimeConverter}}" />
    <DataGridTextColumn.Binding>
        <MultiBinding Converter="{StaticResource TimeConverter}">
            <Binding Path="FromDate" />
            <Binding Path="AttendDate" ElementName="UC" />
        </MultiBinding>
    </DataGridTextColumn.Binding>
</DataGridTextColumn>

但是IMultiValueConverter.Convert - 它需要多个参数 - 仅在格式化显示时调用。在编辑时调用 IMultiValueConverter.ConvertBack,只需要一个参数 - 输入的字符串。

我该怎么做?

(我不使用MVVM;不是我可以改变的东西。)

2 个答案:

答案 0 :(得分:0)

解决方案的一个想法是让另一个属性只有一个getter来合并你想要的信息。

类似

property string Time {get {return this.FromDate.toshortdate().tostring() + AttendDate.hour.tostring() + attenddate.minutes.tostring()}; }

代码可能不是这样,但是你可以绑定这个属性来显示你想要的信息。

的问候,

<强> ============= EDIT ===========

我试过这个,一个非常简单的例子......不知道它是否适合你:

XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:conv ="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <conv:TimeConverter x:Key="tmeConverter"></conv:TimeConverter>
    </Window.Resources>

    <Grid>
        <DataGrid ItemsSource="{Binding listExample}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="teste" >
                    <DataGridTextColumn.Binding>
                        <MultiBinding Converter="{StaticResource tmeConverter}">
                            <Binding Path="FromDate" />
                            <Binding Path="AttendDate" />
                        </MultiBinding>
                    </DataGridTextColumn.Binding>
                </DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

背后的代码(.cs)

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public List<Example2> listExample { get; set; }

        public Example2 Test { get; set; }

        public MainWindow()
        {
            InitializeComponent();
            this.listExample = new List<Example2>();
            //listExample.Add(new Example { IsChecked = false, Test1 = "teste" });
            //listExample.Add(new Example { IsChecked = false, Test1 = "TTTTT!" });

            this.Test = new Example2 { AttendDate = "1ui", FromDate = "ff" };
            this.listExample.Add(this.Test);

            DataContext = this;


        }
    }
}

和Example2类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApplication1
{
    public class Example2
    {
        public string FromDate { get; set; }

        public string AttendDate { get; set; }
    }
}

转换器:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;

namespace WpfApplication1
{
    class TimeConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return values[0].ToString() + values[1].ToString();
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

最后一个窗口显示3列,如果我更改最后两列,则会自动编辑第一列。

是吗?

答案 1 :(得分:0)

去掉DataGridTextColumn并使用DataGridTemplateColumn和CellTemplate,其中包含绑定到多重绑定的文本块,以及包含TextBox绑定到FromDate的单元格编辑模板,可能通过短日期转换器,具体取决于您打算实现的可用性。

关于可能的解决方案:

<强> XAML

    <StackPanel>
    <StackPanel Orientation="Horizontal">
        <Label>From time</Label>
        <DatePicker SelectedDate="{Binding FromTime}"/>
    </StackPanel>
    <DataGrid ItemsSource="{Binding AllUsers}" AutoGenerateColumns="False">
        <DataGrid.Resources>
            <local:TimeConverter x:Key="TimeConverter"/>
        </DataGrid.Resources>
        <DataGrid.Columns>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate DataType="local:UserViewModel">
                        <TextBlock>
                            <TextBlock.Text>
                                <MultiBinding Converter="{StaticResource TimeConverter}">
                                    <Binding ElementName="root" Path="DataContext.FromTime"/>
                                    <Binding Path="AttendTimeHour"/>
                                    <Binding Path="AttendTimeMinute"/>
                                </MultiBinding>
                            </TextBlock.Text>
                        </TextBlock>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate DataType="local:UserViewModel">
                        <StackPanel Orientation="Horizontal">
                            <TextBlock>
                                <Run>Attend on </Run>
                                <Run Text="{Binding ElementName=root, Path=DataContext.FromTime, StringFormat=d}"/>
                                <Run> at </Run>
                            </TextBlock>
                            <TextBox Text="{Binding AttendTimeHour}"/><TextBlock>:</TextBlock>
                            <TextBox Text="{Binding AttendTimeMinute}"/>
                        </StackPanel>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</StackPanel>

查看模型(UserViewModel)部分:

    private DateTime _attendTime;

    public DateTime AttendTime
    {
        get { return _attendTime; }
        set
        {
            if (value == _attendTime) return;
            _attendTime = value;
            OnPropertyChanged();
            OnPropertyChanged("AttendTimeHour");
            OnPropertyChanged("AttendTimeMinute");
        }
    }

    public int AttendTimeHour
    {
        get { return attendTimeHour; }
        set
        {
            if (value.Equals(attendTimeHour)) return;
            attendTimeHour = value;
            AttendTime = new DateTime(AttendTime.Year, AttendTime.Month, AttendTime.Day, AttendTimeHour, AttendTime.Minute, AttendTime.Second);
            OnPropertyChanged();
        }
    }

    private int _attendTimeMinute;

    public int AttendTimeMinute
    {
        get { return _attendTimeMinute; }
        set
        {
            if (value == _attendTimeMinute) return;
            _attendTimeMinute = value;
            AttendTime = new DateTime(AttendTime.Year, AttendTime.Month, AttendTime.Day, AttendTime.Hour, AttendTimeMinute, AttendTime.Second);
            OnPropertyChanged();
        }
    }

转换器

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Length < 2) return null;
        if (!(values[0] is DateTime && values[1] is int && values[2] is int)) return null;

        var fromDate = (DateTime) values[0];
        var attendTimeHour = (int) values[1];
        var attendTimeMinutes = (int)values[2];

        var result = new DateTime(fromDate.Year, fromDate.Month, fromDate.Day, attendTimeHour, attendTimeMinutes, 0);
        return result.ToString();
    }