将 DatePicker 附加到另一个 UI 元素

Attach DatePicker to another UI Element

我有

<StackPanel Orientation="Horizontal">
    <Label Content="{Binding WidgetSubTitle}" Style="{StaticResource WidgetSubTitleStyle}" />

    <DatePicker SelectedDate="{Binding SelectedDate}">
        <DatePicker.Resources>
            <Style TargetType="DatePickerTextBox">
                <Setter Property="Visibility" Value="Collapsed" />
                <Setter Property="IsReadOnly" Value="True" />
            </Style>
        </DatePicker.Resources>
    </DatePicker>
</StackPanel>

看起来像

我想去掉日历图标,取而代之的是 'attach' 我 Label 的日期选择器。单击标签时,我想打开选择器(它在我的视图模型中具有到 DateTime 属性 的双向绑定)。我也可以用按钮替换 Label,这样我就可以从它的命令中受益,这不是问题。

我不知道该怎么做。我见过一个解决方案,将 Calendar 放在 Popup 中,但这对我来说似乎使事情复杂化。

我能想到的一个解决方案是 - 隐藏整个 DatePicker 控件(Visibility = Collapsed)并在单击 button/label 时,仅打开该选择器的日历弹出部分的可见性.虽然不太清楚样式...

您必须为您的 DatePicker 控件编写自定义样式。它可能看起来有点像让您和您提到的解决方案复杂化,但事实并非如此。它是使 WPF 如此出色的原因之一。

在 WPF ControlTemplates 中,您通常有部件,因此 Controll 的实现知道如何处理哪个 UI 元素。

对于 DatePicker,您有 PART_ButtonPART_TextBox,您需要根据自己的需要对其进行自定义。 IE。删除实际按钮并为其添加标签。

您可以阅读所有需要的内容,包括 msdn 上的一个很好的示例。

https://msdn.microsoft.com/en-us/library/ff468215(v=vs.110).aspx

您可以通过更改其 ControlTemplate 来完全改变 WPF 控件的外观。在这种情况下,您可以为 DatePicker 控件定义一个自定义模板,基本上使其看起来像一个按钮,然后为按钮定义另一个模板,使其看起来像一个标签。像这样:

<DatePicker>
    <DatePicker.Template>
        <ControlTemplate TargetType="DatePicker">
            <Grid x:Name="PART_Root" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                <Button x:Name="PART_Button">
                    <Button.Template>
                        <ControlTemplate TargetType="Button">
                            <Label Content="{Binding WidgetSubTitle}" Style="{StaticResource WidgetSubTitleStyle}" />
                        </ControlTemplate>
                    </Button.Template>
                </Button>
                <Popup x:Name="PART_Popup" AllowsTransparency="True" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_TextBox}" StaysOpen="False"/>
            </Grid>
        </ControlTemplate>
    </DatePicker.Template>
</DatePicker>

这样做的好处是,即使更改外观,控件的功能也保持不变。