Пользовательский календарь WPF без кнопок «Назад» и «Следующий» и без параметра режима отображения

Я создаю 12-месячный календарь, используя отдельные элементы управления календарем для каждого месяца. Поскольку я управляю календарями (январь-декабрь) с помощью отдельных кнопок следующего года и предыдущего года, я хочу удалить кнопки предыдущего и следующего элемента календаря из отдельных календарей и отключить возможность изменения режима отображения.

Поскольку я новичок в XAML и мне удобнее делать это в коде, я бы предпочел изменить стиль во время выполнения, но хотел бы узнать, как это сделать с помощью XAML, но мне очень трудно найти пример того, как кто-то что-то делает как это.

Надеюсь, кто-то может помочь.


person Chris    schedule 26.10.2012    source источник


Ответы (3)


Я бы отослал вас к этой статье, чтобы получить общее представление об управлении календарем. .

Короче говоря, вам нужно изменить CalendarItemStyle и удалить PART_PreviousButton и PART_NextButton из его шаблона. Вы можете найти шаблон по умолчанию для всех частей управления календарем здесь.

Когда вы создаете новый стиль элемента календаря без этих частей, установите для него значение CalendarItemStyle вашего календаря в XAML.

person dodsky    schedule 26.10.2012
comment
Спасибо за ответ. Можно ли это сделать в коде С# или это нужно сделать в XAML? - person Chris; 26.10.2012
comment
Теоретически можно, но я бы не советовал. Это было бы много неподдерживаемого кода. Кроме того, я не знаю, к каким примерам кода я мог бы отослать вас для начала... - person dodsky; 27.10.2012
comment
Хорошо.. Я перешел по одной из ссылок, которые вы отправили ранее. Я заставил его работать с помощью WPFToolkit. Кажется, я видел еще один пример, в котором используются примитивы без набора инструментов. Я пытаюсь ограничить сборки. Спасибо .. за помощь .. Если вы знаете пример, в котором не используется WPFToolkit, это было бы здорово, но я тоже собираюсь посмотреть. - person Chris; 27.10.2012

Что ж, после долгих поисков, множества примеров и Додского, указывающего мне правильное направление. Я понял это и почувствовал, что обмен информацией — лучший способ отплатить сообществу разработчиков. Поскольку я новичок в XAML, это маленькая победа в битве проектов, в которой я участвую. Надеюсь, это поможет другим новичкам, таким как я.

Я постараюсь объяснить как можно лучше, чтобы показать вам, как манипулировать календарем так, как вам нужно.

В моем пользовательском контроле

<Calendar CalendarItemStyle="{DynamicResource calItemStyle}"  Name="calJan"    
 HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" 
 HorizontalAlignment="Center" VerticalAlignment="Center" OverridesDefaultStyle="False" 
 IsEnabled="True" />

Некоторые параметры избыточны, главное - Динамический ресурс.

CalendarItemStyle="{DynamicResource calItemStyle}"

В моем ResourceDictionary я добавил пространство имен

xmlns:primitives="clr-namespace:System.Windows.Controls.Primitives;assembly=PresentationFramework"

Вы также захотите добавить ссылку 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="&lt;"
                                Focusable="False" 
                                Visibility="Hidden"
                                />

                    <Button x:Name="PART_NextButton" 
                                DockPanel.Dock="Right"
                                Content="&gt;" 
                                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>

Я решил скрыть кнопки «Назад» и «Далее» на тот случай, если удаление вызовет проблемы с какими-либо событиями, но в остальном он делает то, что я хочу, и я могу добавлять или удалять функции по мере необходимости.

Надеюсь, это поможет другим.

person Chris    schedule 27.10.2012
comment
Хорошо, после этого я обнаружил кое-что, с чем сейчас пытаюсь разобраться. 1. Мои дни недели пропали? 2. Мне нужно удалить дополнительные дни из каждого месяца и показать только дни для этого конкретного месяца 3. удалить или остановить событие, когда пользователь выбирает день из предыдущего или следующего месяца. 4. измените тип для Part_HeaderButton, так как это действительно не должно быть кнопкой, также нужно просто отображать название месяца, а не год. Много дел .. если другие знают какие-то подсказки, дайте знать мне и другим. Спасибо - person Chris; 27.10.2012
comment
Спасибо за это, очень полезно. Просто хотел добавить. Измените <DataTemplatex:Key="DayTitleTemplate"> на <DataTemplate x:Key="{x:Static CalendarItem.DayTitleTemplateResourceKey}"> и вы вернете свои дни недели - person QurakNerd; 03.06.2021

Как и Крис, я не хотел возиться с кучей XAML. Мне также нужно было скрыть/показать динамически. Я предполагаю, что есть способ сделать это с помощью привязок в XAML, но я подумал, что это довольно простое начало. Просто добавьте новый класс с этим кодом, а затем используйте этот производный элемент управления.

Изменить: я обновил его, чтобы иметь свойство, которое вы можете установить, HidePrevNextBtns. Если отмечено/истинно, кнопки будут скрыты. Этот код делает пару предположений. Во-первых, в шаблоне также будут кнопки «предыдущий/следующий», а во-вторых, они будут видны по умолчанию.

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;
        }
    }
}
person eselk    schedule 30.08.2013