WPF 自定义日历,没有上一个和下一个按钮,也没有显示模式选项
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13086869/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF Custom Calendar without Previous and Next buttons and no displaymode option
提问by Chris
I am creating a 12 month calendar using the individual calendar controls for each month. Since I am controlling the calendars (Jan - Dec) via separate next year and previous year buttons, I want to remove the previous and next calendaritem buttons from the individual calendars and disable the ability to change the display mode.
我正在使用每个月的单独日历控件创建一个 12 个月的日历。由于我通过单独的明年和上一年按钮控制日历(一月 - 十二月),我想从单个日历中删除上一个和下一个日历项按钮并禁用更改显示模式的功能。
Since I am new to XAML and more comfortable with doing this in code, I would prefer to change the style at runtime but willing to learn how to make it happen via XAML but I am having a very difficult time finding an example of someone doing something like this.
由于我是 XAML 的新手并且更习惯在代码中执行此操作,因此我更喜欢在运行时更改样式但愿意学习如何通过 XAML 实现它,但是我很难找到某人做某事的示例像这样。
Hope someone can help.
希望有人能帮忙。
回答by dodsky
I would refer you to thisarticle to get some basic understanding of Calendar control.
我会向您推荐这篇文章,以对 Calendar 控件有一些基本的了解。
In short, you need to modify CalendarItemStyle and remove PART_PreviousButton and PART_NextButton from its template. You can find default template for all parts of Calendar control here.
简而言之,您需要修改 CalendarItemStyle 并从其模板中删除 PART_PreviousButton 和 PART_NextButton。您可以在此处找到 Calendar 控件所有部分的默认模板。
When you create a new calendar item style without those parts then set it to CalendarItemStyleproperty of your calendar in XAML.
当您创建没有这些部分的新日历项样式时,请将其设置为XAML 中日历的 CalendarItemStyle属性。
回答by Chris
Well, after lots of digging, many examples and Dodsky pointing me in the right direction. I figured it out and felt that sharing was the best way to repay the developer community. Since, I am new to XAML it is a small victory in project battle that I am in. Hopefully, it will help other newbies like me.
好吧,经过大量挖掘、许多示例和 Dodsky 为我指明了正确的方向。我想通了,觉得分享是回报开发者社区最好的方式。因为,我是 XAML 的新手,这是我在项目战中的一个小胜利。希望它会帮助像我这样的其他新手。
I will try to explain the best way that I can to show you how to manipulate the calendar any way that you need to.
我将尝试以最好的方式向您展示如何以您需要的任何方式操作日历。
In my UserControl
在我的用户控件中
<Calendar CalendarItemStyle="{DynamicResource calItemStyle}" Name="calJan"
HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
HorizontalAlignment="Center" VerticalAlignment="Center" OverridesDefaultStyle="False"
IsEnabled="True" />
Some of the parameters are overkill, the main point is the Dynamic Resource
有些参数有点矫枉过正,重点是动态资源
CalendarItemStyle="{DynamicResource calItemStyle}"
In my ResourceDictionary, I added the namespace
在我的 ResourceDictionary 中,我添加了命名空间
xmlns:primitives="clr-namespace:System.Windows.Controls.Primitives;assembly=PresentationFramework"
You will also want to add the PresentationFramework reference to your project, if it is not already there.
您还需要将 PresentationFramework 引用添加到您的项目中(如果它尚未存在)。
<Style x:Key="calItemStyle"
TargetType="primitives:CalendarItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="primitives:CalendarItem">
<ControlTemplate.Resources>
<DataTemplate x:Key="DayTitleTemplate">
<TextBlock Text="{Binding}"
HorizontalAlignment="Center" />
</DataTemplate>
</ControlTemplate.Resources>
<DockPanel Name="PART_Root"
LastChildFill="True">
<Button x:Name="PART_PreviousButton"
DockPanel.Dock="Left"
Content="<"
Focusable="False"
Visibility="Hidden"
/>
<Button x:Name="PART_NextButton"
DockPanel.Dock="Right"
Content=">"
Focusable="False"
Visibility="Hidden"
/>
<Button x:Name="PART_HeaderButton"
DockPanel.Dock="Top"
FontWeight="Bold"
Focusable="False" />
<Grid>
<Grid x:Name="PART_MonthView"
Visibility="Visible">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
</Grid>
<Grid x:Name="PART_YearView"
Visibility="Hidden">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
</Grid>
</Grid>
<Rectangle x:Name="PART_DisabledVisual" Opacity="0" Visibility="Collapsed" Fill="#A5FFFFFF"/>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="PART_DisabledVisual" Property="Visibility" Value="Visible" />
</Trigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type Calendar}}, Path=DisplayMode}" Value="Year">
<Setter TargetName="PART_MonthView" Property="Visibility" Value="Hidden" />
<Setter TargetName="PART_YearView" Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type Calendar}}, Path=DisplayMode}" Value="Decade">
<Setter TargetName="PART_MonthView" Property="Visibility" Value="Hidden" />
<Setter TargetName="PART_YearView" Property="Visibility" Value="Visible" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I chose to hide the Previous and Next buttons, just in case removal caused a problem with any events but otherwise, it does what I want it to and I can add or take away features as needed.
我选择隐藏“上一个”和“下一个”按钮,以防万一删除导致任何事件出现问题,否则,它会执行我想要的操作,我可以根据需要添加或删除功能。
Hope this helps others.
希望这对其他人有帮助。
回答by eselk
Like Chris, I didn't want to mess with a ton a XAML. I also needed to hide/show dynamically. I imagine there is a way to do this with bindings in XAML as well, but I thought this was a pretty simple start. Just add a new class with this code, then use this derived control instead.
像 Chris 一样,我不想弄乱大量的 XAML。我还需要动态隐藏/显示。我想也有一种方法可以使用 XAML 中的绑定来做到这一点,但我认为这是一个非常简单的开始。只需使用此代码添加一个新类,然后改用此派生控件即可。
Edit: I updated it to have a property you can set, HidePrevNextBtns. If checked/true, buttons will be hidden. This code does make a couple assumptions. One is that the template will also have prev/next buttons, and other is they will be visible by default.
编辑:我将其更新为具有您可以设置的属性 HidePrevNextBtns。如果选中/true,按钮将被隐藏。这段代码做了几个假设。一个是模板也有上一个/下一个按钮,另一个是默认情况下它们是可见的。
class MyCalendar : Calendar
{
public Button PrevBtn;
public Button NextBtn;
protected bool _HidePrevNextBtns;
public bool HidePrevNextBtns
{
get
{
return (_HidePrevNextBtns);
}
set
{
_HidePrevNextBtns = value;
if (PrevBtn != null)
{
PrevBtn.Visibility = _HidePrevNextBtns ? Visibility.Hidden : Visibility.Visible;
NextBtn.Visibility = _HidePrevNextBtns ? Visibility.Hidden : Visibility.Visible;
}
}
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var cal = this.Template.FindName("PART_CalendarItem", this) as CalendarItem;
cal.Loaded += new RoutedEventHandler(cal_Loaded);
}
void cal_Loaded(object sender, RoutedEventArgs e)
{
var cal = sender as CalendarItem;
PrevBtn = cal.Template.FindName("PART_PreviousButton", cal) as Button;
NextBtn = cal.Template.FindName("PART_NextButton", cal) as Button;
if (_HidePrevNextBtns)
{
PrevBtn.Visibility = Visibility.Hidden;
NextBtn.Visibility = Visibility.Hidden;
}
}
}

