在新的Windows 10日历视图上显示/样式化额外的信息
本文关键字:样式 信息 显示 Windows 日历 视图 | 更新日期: 2023-09-27 18:08:59
我最近开始开发一个Windows 10应用程序,它需要在CalendarView上显示事件和额外的信息。随着新API的发布,还引入了一个新的CalendarView组件,所以我决定尝试一下。这是一个不错的小部件,但自定义一直是一个地狱。
我已经到了可以使用ControlTemplate显示自定义信息的地步,但是用VisualState绑定事件和样式是相当困难的。
这是我用一个样式包装的ControlTemplate。
<Style x:Key="dayItemStyle" TargetType="CalendarViewDayItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CalendarViewDayItem">
<Grid x:Name="DayItemEventListRoot">
<ListView ItemsSource="{TemplateBinding DataContext}" Padding="20,0,0,0" x:Name="EventInfoList"
IsItemClickEnabled="True" cm:Message.Attach="[Event ItemClick] = [ListTapped]">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="EventInfoPanel" Orientation="Horizontal">
<TextBlock x:Name="EventTime" Text="{Binding Date, Converter={StaticResource StringFormatter}, ConverterParameter='{0:HH:mm'} }"
Foreground="{Binding Foreground, RelativeSource={RelativeSource Self}}" >
</TextBlock>
<TextBlock x:Name="EventDesc" Text="{Binding Name}" Padding="5,0,0,0" Foreground="Black" >
</TextBlock>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="Normal" />
<VisualState x:Name="Today" >
<VisualState.Setters>
<Setter Target="EventTime.Foreground" Value="White" />
<Setter Target="EventDesc.Foreground" Value="White" />
<Setter Target="EventTime.Text" Value="DASFASDDF" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
然后直接在CalenderView组件上设置样式。
<CalendarView Name="FlowCalendar" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" VerticalDayItemAlignment="Top" HorizontalDayItemAlignment="Left"
Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="5" Grid.RowSpan="4" CalendarViewDayItemChanging="FlowCalendar_CalendarViewDayItemChanging"
CalendarViewDayItemStyle="{StaticResource dayItemStyle}">
</CalendarView>
额外的信息和状态由代码隐藏中的CalenderViewDayItemChanging事件控制。
private void FlowCalendar_CalendarViewDayItemChanging(CalendarView sender, CalendarViewDayItemChangingEventArgs args)
{
if(args.Item.Date.Date.Equals(DateTime.Now.Date))
{
VisualStateManager.GoToState(args.Item, "Today", false);
// Testing, gives NullPointerException
//TextBlock bla = (TextBlock) args.Item.FindName("EventTime");
//bla.Text = "SDADASFASDF";
}
if (args.Phase == 0)
{
var eventsByDate = ViewModel.Upcoming.FirstOrDefault(eg => eg.Key.Date == args.Item.Date.Date);
if (eventsByDate != null)
{
args.Item.DataContext = eventsByDate.ToList();
}
}
}
设置视觉状态没有任何作用(我已经检查了它是否被调用),将VisualState(Group)移出ControlTemplate只是给了我一个无法找到目标的错误。
我希望通过视觉状态来控制事件列表视图样式,目前是自定义的,因为我不确定CalendarViewDayItem有什么内置状态。我对视觉状态很陌生,所以任何提示都是非常感谢的。
谢谢。
您的代码将无法工作,因为VisualStateManager.GoToState
将Control
作为第一个参数;然而,您的VisualStateManager
是在Panel
类型的StackPanel
中定义的。
你将需要实现你自己的VSM
,它需要一个Panel
代替。看看这篇文章的答案,看看如何做到这一点。
StackPanel
s(注意,因为它在ListView
中,可能有多个),然后调用ExtendedVisualStateManager.GoToState
.
我建议你把这个模板包装在一个UserControl
中(通过这样做,你VSM
GoToStateAction
代替IsToday
)来控制状态。然后,您可以使用ElementName
绑定将CalendarViewDayItem
级别的属性传递给IsToday
,以便进行状态更改。
更新我实际上是错误的需要使用ExtendedVisualManager
来改变视觉状态。因为它已经在UserControl
中了,所以你可以直接调用VisualStateManager.GoToState(this, "statename", flag);
。
但是,你定义依赖属性的方式是错误的。
用下面的代码替换后面的代码,它应该可以工作。
public bool IsToday
{
get { return (bool)GetValue(IsTodayProperty); }
set { SetValue(IsTodayProperty, value); }
}
public static readonly DependencyProperty IsTodayProperty =
DependencyProperty.Register("IsToday", typeof(bool), typeof(EventListTemplate), new PropertyMetadata(false, OnIsTodayChanged));
static void OnIsTodayChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var template = (EventListTemplate)d;
if ((bool)e.NewValue)
{
var stateset = VisualStateManager.GoToState(template, "DayItemToday", false);
Debug.WriteLine("did it:", stateset);
}
}