3.前一个月 前一年 下一个月 下一年的切换
首先来看界面,上部分比较好些 都是一些死的东西,添加一些button和textblock即可。
下面的部分我们采用 一个listbox 来实现,只不过ItemsPanel 我们设置成grid
<ListBox SelectionChanged="MonthListBox_SelectionChanged" PreviewMouseLeftButtonDown="MonthListBox_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="MonthListBox_PreviewMouseLeftButtonUp" x:Name="MonthListBox" Padding="-4" BorderThickness="0" Background="White" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Grid.Row="1">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Grid Margin="5" >
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
然后 我们往里面添加数据,我们看到第一行 有一部分空白,然后剩下的都是数字,需要计算一下每个月从哪天开始 是有日期的。
/// <summary>
/// 刷新整个控件
/// </summary>
/// <param name="useful"></param>
private void FreshControl()
MonthListBox.Items.Clear();
DateTextBlock.Text = _curTime.ToString("yyyy年MM月dd日");
DateTime monthStart = DateTime.Parse(_curTime.AddDays(1 - _curTime.Day).ToString("yyyy-MM-dd"));//计算改月第一天
int whatDay = Convert.ToInt32(monthStart.DayOfWeek.ToString("d"));//计算第一天的是周几
InitMonthListBox(whatDay);
_curMonth = Convert.ToInt32(_curTime.ToString("MM"));
_curYear = Convert.ToInt32(_curTime.ToString("yyyy"));
MonthAndYearTextBlock.Text = _day[_curMonth - 1] + " " + _curYear;
然后初始化 这个控件
/// <summary>
/// 初始化日期面板
/// </summary>
/// <param name="whatDay">该月从第几天开始</param>
/// <param name="useful"></param>
private void InitMonthListBox(int whatDay)
MonthListBox.Items.Clear();
var col = whatDay;
var row = 0;
//没有的日期 用空白替代
for (int i = 0; i < whatDay; i++)
ListBoxItem lbi = new ListBoxItem();
lbi.Style = MonthListBox.FindResource("MyListBoxStyle") as Style;
Grid.SetRow(lbi, 0);
Grid.SetColumn(lbi, i);
lbi.IsEnabled = false;
MonthListBox.Items.Add(lbi);
for (int n = 1; n <= DateTime.DaysInMonth(_curYear, _curMonth); n++)
ListBoxItem lbi = new ListBoxItem();
lbi.MouseEnter += Lbi_MouseEnter;
lbi.Style = this.FindResource("MyListBoxStyle") as Style;
Grid.SetRow(lbi, row);
Grid.SetColumn(lbi, col);
col++;
if (col / 7 >= 1)
row++;
col = 0;
lbi.IsEnabled = false;
if (n<15) //前14天可选
lbi.IsEnabled = true;
Label lb = new Label();
lb.Content = n;
lbi.Content = lb;
if ((n - 1 + whatDay) % 7 == 0 || (n - 1 + whatDay) % 7 == 6) //周末特殊颜色
lb.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#E67B74")); ;
lbi.Tag = n;
MonthListBox.Items.Add(lbi);
控件画出来了,然后再看日期可listbox选不可选的设置,这个比较简单,其实就是设置listboxItem.IsEnabled 事件
接着看前一个月的触发事件(前一年 后一年 后一个月都相同)
其实只需要将_curTime 计算到上一个月就好了(注意这个要判定1月 这种情况)
private void LastMonthButton_Click(object sender, RoutedEventArgs e)
_curTime = _curTime.AddMonths(-1) == _curTime ? _curTime.AddYears(-1) : _curTime.AddMonths(-1); ;
FreshControl();
接下来 对比一下wpf 提供的Calendar,发现他可以框选日期的,如何实现这一功能呢?
listbox是支持多选的(SelectionMode = SelectionMode.Multiple),但是他的多选并不支持框选的,这里我们自己写。(利用鼠标按下,抬起,和划过处理)
(这里MouseDown等事件都触发不了,只能用PreviewMouseLeftButtonDown等相关事件折中处理下)
其实说白了 就是鼠标点击的时候记录一下开始时间,然后划过的时候,将开始到划过的这个日期 都设为选中就好了。
这块需要先将SelectionMode = SelectionMode.Multiple 这个设置好。
对应的相关事件
bool isMouseClick = false;
bool isMulitSelect = false;
private void MonthListBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
MonthListBox.SelectedIndex = -1;
isMouseClick = true;
private void MonthListBox_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
isMouseClick = false;
isMulitSelect = false;
var items = MonthListBox.SelectedItems;
foreach (var temp in items)
var selectItem = temp as ListBoxItem;
int days = 0;
int.TryParse((selectItem.Content as Label).Content.ToString(), out days);
Console.WriteLine(days + "日");
int start = 0;
/// <summary>
/// 选中不同的日期
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MonthListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
var item = MonthListBox.SelectedItem as ListBoxItem;
if (item == null)
return;
Console.WriteLine();
int.TryParse((item.Content as Label).Content.ToString(), out _curDay);
DateTextBlock.Text = _curYear + "年" + _curMonth + "月" + _curDay + "日";
if (isMouseClick && isMulitSelect == false)
isMulitSelect = true;
start = _curDay;
Console.WriteLine("MonthListBox_SelectionChanged"+ _curYear + "年" + _curMonth + "月" + _curDay + "日");
private void Lbi_MouseEnter(object sender, MouseEventArgs e)
if (isMouseClick && isMulitSelect)
var item = sender as ListBoxItem;
if (item == null)
return;
int enddays = 0;
int.TryParse((item.Content as Label).Content.ToString(), out enddays);
int startdays = start;
if (enddays < startdays)
int tempday = startdays;
startdays = enddays;
enddays = tempday;
foreach (ListBoxItem temp in MonthListBox.Items)
if (Convert.ToInt16(temp.Tag) >= startdays && Convert.ToInt16(temp.Tag) <= enddays)
temp.IsSelected = true;
temp.IsSelected = false;
ok 这样就能模拟出框选的功能了。就先这样把,源码稍后再传。
wpf提供了Calendar 控件来进行时间选择,但是有些东西不太好改,就自定义一个自己的控件。目标是做一个类似于qq 聊天记录里面的那个日期选择控件需要实现的基本功能1.日期的显示2.某些日期可选,某些不可选3.前一个月 前一年 下一个月 下一年的切换首先来看界面,上部分比较好些 都是一些死的东西,添加一些button和textblock即可。下面的部分我们采用 ...
申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接。
本文主要内容:
日历控件Calendar自定义样式;
日期控件DatePicker自定义样式,及Label标签、水印、清除日期功能扩展;
二.Calendar自定义样式
先看看效果:
从上面图可以看...
粗略的在代码上做了些注释
blend 生成出来的模版 有的时候 会生成 跟 vs ui界面不兼容的代码 会导致可视化设计界面 报错崩溃掉 但是确不影响 程序的编译运行
这个样式表 在vs 里会提示动画不兼容 Foreground属性 报错
先上图看下样式
add_months(x,y)或者add_months(times,months)函数:用途:这个函数用于计算在时间x之上机上Y个月后的时间值,要是Y的值为负数的话就是这个时间点之间的时间值(这个时间-Y个月)例如:
查询当前时间1个月以前的时间:
select add_months(sysdate,-1) from dual;
查询当前时间1个月以后的时间:
现在智能手机里面滚动选择的日期选择器一直让人感觉惊艳,后来一个客户的需求,需要在WPF里面实现认识的效果,在网上找了找,一直没有相关的资源,很是奇怪。后来自己用WPF试着写了个,效果还不错。当然还不是特别的效果好,后续还有优化的空间。
【滚动的话,需要触摸屏支持】
一开始参考了网上一位博主的做法,一开始设定好三个标签,然后手指滑动的时候改变这三个标签的位置,从而实现滑动的效果,从结果上,这个效果还是蛮不错的,但是由于改变的时候是三个标签一起变,因此会产生一瞬间的回弹感,不太适合,且其动画效果有些难以处理,因此作罢。
在找资料的时候,看见了
WPF 循环显示列表这篇文章,其本意是构建一个窗口,每次滚动就刷新窗口中的值,基于这
可以通过修改WPF ListView中每个Item的样式来实现自定义每一行的颜色。具体步骤如下:
1. 在XAML中定义ListView的ItemContainerStyle,指定ItemContainerStyle为ListView.ItemContainerStyle属性的值。例如:
<ListView x:Name="myListView">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<!--在这里定义Item的样式-->
</Style>
</ListView.ItemContainerStyle>
</ListView>
2. 在Style中添加一个Trigger,根据Item的数据内容来设置颜色。例如:
<Style TargetType="ListViewItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Status}" Value="New">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
<DataTrigger Binding="{Binding Status}" Value="Completed">
<Setter Property="Background" Value="LightGray"/>
</DataTrigger>
</Style.Triggers>
</Style>
在这个例子中,根据绑定到ListViewItem的数据对象的Status属性的值来设置Item的背景颜色。
希望这个回答对你有帮助!
报错:Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
48317