用户在组合框中选择一些东西,其他东西被发送到依赖属性

时间:2010-02-18 08:27:40

标签: c# .net wpf datetime format-string

在我的应用程序中,用户可以选择日期的显示方式。大多数standard datetime format strings都可以选择。我现在的问题是普通用户不理解“m”和“D”之间的区别。 我想要做的是更改这一点,以便像excel那样,而不是显示格式字符串,我展示了使用该格式的任意日期的样子。

WPF组合框SelectedItem绑定到日期格式选择器clas中的依赖项属性,包含此日期选择器的另一个控件也绑定到该属性。

示例

  1. 用户选择“January,15”,因此依赖属性设置为“m”。
  2. 通过代码隐藏,依赖属性的值设置为“D”,组合框更新为显示“1970年1月15日星期四”作为选定项目。
  3. 我尝试使用转换器,但ConvertBack是不可能的,因为我无法提取用于创建特定日期的格式字符串。

1 个答案:

答案 0 :(得分:1)

您可以创建一个类DateFormatChoice,其中包含格式代码的属性(例如,“m”或“D”)以及以这种方式格式化的当前日期的属性。

public class DateFormatChoice {
    public string FormatCode { get; private set; }
    public string CurrentDateExample {
        get { return DateTime.Now.ToString( FormatCode ) }
    }

    public DateFormatChoice( string standardcode ) {
        FormatCode = standardcode;
    }
}

您可以使用CurrentDateExample中的DataTemplate或ComboBox的DisplayMemberPath将ComboBox绑定到这些组合的集合。您可以直接将这些对象与日期格式选择器类一起使用,DatePicker绑定到所选FormatCode对象的DateFormatChoice属性,也可以设置ValueMemberPath属性在原始ComboBox上的FormatCode属性,并使用ComboBox上的SelectedValue来获取/设置所选内容。不使用ValueMember可能会更容易一些。


这是一个更完整的例子。它使用上面的DateFormatChoice类。

首先是数据收集。

public class DateFormatChoices : List<DateFormatChoice> {
    public DateFormatChoices() {
        this.Add( new DateFormatChoice( "m" ) );
        this.Add( new DateFormatChoice( "d" ) );
        this.Add( new DateFormatChoice( "D" ) );
    }
}

然后我为Window创建了简单的ViewModel:

public class ViewModel : INotifyPropertyChanged {
    public event PropertyChangedEventHandler PropertyChanged = ( s, e ) => {
    }; // the lambda ensures PropertyChanged is never null

    public DateFormatChoices Choices {
        get;
        private set;
    }

    DateFormatChoice _chosen;
    public DateFormatChoice Chosen {
        get {
            return _chosen;
        }
        set {
            _chosen = value;
            Notify( PropertyChanged, () => Chosen );
        }
    }

    public DateTime CurrentDateTime {
        get {
            return DateTime.Now;
        }
    }

    public ViewModel() {
        Choices = new DateFormatChoices();
    }

    // expression used to avoid string literals
    private void Notify<T>( PropertyChangedEventHandler handler, Expression<Func<T>> expression ) {
        var memberexpression = expression.Body as MemberExpression;
        handler( this, new PropertyChangedEventArgs( memberexpression.Member.Name ) );
    }
}

我没有接受标准字符串格式代码的日期选择器控件,所以我做了一个非常愚蠢的UserControl(有许多角切)只是为了证明它接收格式代码。我给了它一个名为DateFormatProperty类型string的依赖项属性,并在UIPropertyMetadata中指定了一个更改了值的回调。

<Grid>
    <TextBlock Name="datedisplayer" />
</Grid>

回调:

private static void DateFormatChanged( DependencyObject obj, DependencyPropertyChangedEventArgs e ) {
    var uc = obj as UserControl1;
    string code;
    if ( null != ( code = e.NewValue as string ) ) {
        uc.datedisplayer.Text = DateTime.Now.ToString( code );
    }
}

这就是我在窗口中将它们捆绑在一起的方式。

<StackPanel>
    <StackPanel.DataContext>
        <local:ViewModel />
    </StackPanel.DataContext>
    <ComboBox
        ItemsSource="{Binding Choices}" DisplayMemberPath="CurrentDateExample"
        SelectedItem="{Binding Chosen, Mode=TwoWay}"/>
    <local:UserControl1
        DateFormatProperty="{Binding Chosen.FormatCode}" />
</StackPanel>