WPF -- 自定义控件 (UserControl)(二 下)
程序员文章站
2022-03-04 11:52:02
...
在自定义控件 (UserControl)(二 上)中转载大神的一篇博文。通过一个UserControl例子主要介绍了User Control后台添加依赖项属性,路由事件以及命令的添加以及使用,这篇我主要介绍一下通过通过项目应用后的一些总结。
首先来分析一段前台代码:
<ScrollViewer Grid.Row="4" VerticalScrollBarVisibility="Auto" Margin="0,10,0,0">
<ItemsControl Margin="-20,0,0,0" x:Name="ResourceList1" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Background="Transparent" BorderThickness="0"
ItemsSource="{Binding PoliceBinding.MemberInfoData,Converter={StaticResource filterByMemberRoleConverter}, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="ResourceGrid">
<IMViews:SummaryScoreResource
UserName="{Binding DataContext.UserName,ElementName=ResourceGrid}"
OrgName="{Binding DataContext.OrgName,ElementName=ResourceGrids}"
ImageSource="{Binding DataContext.HeadImageSource,ElementName=ResourceGrid}"
LoginId="{Binding DataContext.LoginId,ElementName=ResourceGrid}"
UserId="{Binding DataContext.UserId,ElementName=ResourceGrid}"
Value="{Binding DataContext.UsersScores,ElementName=ResourceGrid,UpdateSourceTrigger=PropertyChanged}"
Colors="{Binding TextColor}"
></IMViews:SummaryScoreResource>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto" >
</StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
/// <summary>
/// 成员对象
/// </summary>
public ObservableCollection<MemberInfoModel> MemberInfoData
{
get
{
return _MemberInfoData??(_MemberInfoData=new ObservableCollection<MemberInfoModel>());
}
set
{
_MemberInfoData = value; RaisePropertyChanged(() => MemberInfoData); RaisePropertyChanged(() => MemberCount);
RefreshUser();
}
}
MemberInfoModel.cs
using System;using System.Collections.Generic;using System.Linq;using System.Text;using Telewave.CompositeOperations.Model.BusinessModel.Base;using Telewave.CompositeOperations.Model.BusinessModel.UserInfo;namespace Telewave.CompositeOperations.Model.BusinessModel{ public class MemberInfoModel: HeadImgBaseModel { public MemberInfoModel(UserInfoModel model):base() { UserId = model.UserId; LoginId = model.LoginId; UserName = model.Name; HeadImageSource = model.HeadImg; OrgId = model.OrgId; OrgName = model.OrgName; Role = model.Roles; TelNumber = model.Mobile; switch(Role) { case "2": ShowRoles = "指挥员"; break; case "3": ShowRoles = "成员"; break; } } public MemberInfoModel() { } private string _UserId; /// <summary> /// 用户id(GUID) /// </summary> public string UserId { get { return _UserId; } set { _UserId = value;RaisePropertyChanged(() => UserId); } } private string _LoginId; /// <summary> /// 登陆ID(警号) /// </summary> public string LoginId { get { return _LoginId; } set { _LoginId = value; RaisePropertyChanged(() => LoginId); } } private string _Tips; /// <summary> /// /// </summary> public string Tips { get { return _Tips; } set { _Tips = value; RaisePropertyChanged(() => Tips); } } private string _Role; /// <summary> /// 角色 /// </summary> public string Role { get { return _Role; } set { _Role = value; RaisePropertyChanged(() => Role); } } private string _TelNumber; /// <summary> /// 电话 /// </summary> public string TelNumber { get { return _TelNumber; } set { _TelNumber = value; RaisePropertyChanged(() => _TelNumber); } } /// <summary> /// 部门名称 /// </summary> private string _OrgName; public string OrgName { get { return _OrgName; } set { _OrgName = value; RaisePropertyChanged(() => OrgName); } } private string _ShowRoles; /// <summary> /// 作战室角色 /// </summary> public string ShowRoles { get { return _ShowRoles; } set { _ShowRoles = value; RaisePropertyChanged(() => ShowRoles); } } private string _OrgId; /// <summary> /// 部门编号 /// </summary> public string OrgId { get { return _OrgId; } set { _OrgId = value; RaisePropertyChanged(() => OrgId); } } private bool _AllowDelete = true; public bool AllowDelete { get { return _AllowDelete; } set { _AllowDelete = value; RaisePropertyChanged(() => AllowDelete); } } private bool _IsSelected; public bool IsSelected { get { return _IsSelected; } set { _IsSelected = value; RaisePropertyChanged(() => IsSelected); } } private bool _AllowSelected; public bool AllowSelected { get { return _AllowSelected; } set { _AllowSelected = value; RaisePropertyChanged(() => AllowSelected); } } private string _UsersScores="0"; /// <summary> /// 作战室成员打分与成员顺序对应 /// </summary> public string UsersScores { get { return _UsersScores; } set { _UsersScores = value; RaisePropertyChanged(() => UsersScores); } } }}
大概需求就是展示群组人员信息的一个列表。
一般展示列表,首先想到的是用ListBox控件,当然可以实现,但是这里的这个列表中内容较多,还又一个打分图框操作(已实现),用ListBox自定义控件实现起来会比较麻烦,而且这个列表中的一些内容已经有过实现,综合考虑,最后还是用ItemsControl ,通过数据模板展示MemberInfoModel对象,数据模板的内容用到UserControl(用户控件)。
<IMViews:SummaryScoreResource
UserName="{Binding DataContext.UserName,ElementName=ResourceGrid}"
OrgName="{Binding DataContext.OrgName,ElementName=ResourceGrids}"
ImageSource="{Binding DataContext.HeadImageSource,ElementName=ResourceGrid}"
LoginId="{Binding DataContext.LoginId,ElementName=ResourceGrid}"
UserId="{Binding DataContext.UserId,ElementName=ResourceGrid}"
Value="{Binding DataContext.UsersScores,ElementName=ResourceGrid,UpdateSourceTrigger=PropertyChanged}"
Colors="{Binding TextColor}"
></IMViews:SummaryScoreResource>
可以看到,数据模板的内容是名为SummaryScoreResource 的一个UserControl,SummaryScoreResource 中的UserName,OrgName等属性都是通过绑定DataContext.UserName,ElementName=ResourceGrid 对应的属性绑定的。
后台操作:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Telewave.CompositeOperations.Views.IMViews
{
/// <summary>
/// SummaryScoreResource.xaml 的交互逻辑
/// </summary>
public partial class SummaryScoreResource : UserControl
{
public SummaryScoreResource()
{
InitializeComponent();
}
#region 单例
private static SummaryScoreResource _instance;
public static SummaryScoreResource Instance
{
get
{
if (_instance == null)
{
_instance = new SummaryScoreResource();
}
return _instance;
}
}
#endregion
/// <summary>
/// 姓名
/// </summary>
public string UserName
{
get { return (string)GetValue(UserNameProperty); }
set { SetValue(UserNameProperty, value); }
}
/// <summary>
/// 提示信息(部门)
/// </summary>
public string OrgName
{
get { return (string)GetValue(OrgNameProperty); }
set { SetValue(OrgNameProperty, value); }
}
/// <summary>
/// 图片路径
/// </summary>
public string ImageSource
{
get
{
return (string)GetValue(ImageSourceProperty);
}
set
{
SetValue(ImageSourceProperty, value);
}
}
/// <summary>
/// 登录名(警号)
/// </summary>
public string LoginId
{
get { return (string)GetValue(LoginIdProperty); }
set { SetValue(LoginIdProperty, value); }
}
/// <summary>
/// 用户id(guid)
/// </summary>
public string UserId
{
get { return (string)GetValue(UserIdProperty); }
set { SetValue(UserIdProperty, value); }
}
/// <summary>
/// 评分间隔值
/// </summary>
public string Increment
{
get { return (string)GetValue(IncrementProperty); }
set { SetValue(IncrementProperty, value); }
}
public static readonly DependencyProperty IncrementProperty =
DependencyProperty.Register("Increment", typeof(string), typeof(SummaryScoreResource),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.AffectsRender));
/// <summary>
/// 最大值
/// </summary>
public string MaxValue
{
get { return (string)GetValue(MaxValueProperty); }
set { SetValue(MaxValueProperty, value); }
}
public static readonly DependencyProperty MaxValueProperty =
DependencyProperty.Register("MaxValue", typeof(string), typeof(SummaryScoreResource),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.AffectsRender));
/// <summary>
/// 最小值
/// </summary>
public string MinValue
{
get { return (string)GetValue(MinValueProperty); }
set { SetValue(MinValueProperty, value); }
}
public static readonly DependencyProperty MinValueProperty =
DependencyProperty.Register("MinValue", typeof(string), typeof(SummaryScoreResource),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.AffectsRender));
/// <summary>
/// 评分值
/// </summary>
public string Value
{
get { return (string)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(string), typeof(SummaryScoreResource),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.AffectsRender));
/// <summary>
/// 状态颜色
/// </summary>
public Brush Colors
{
get { return (Brush)GetValue(ColorsProperty); }
set { SetValue(ColorsProperty, value); }
}
public static readonly DependencyProperty ColorsProperty = DependencyProperty.Register("Colors"
, typeof(Brush), typeof(SummaryScoreResource), new FrameworkPropertyMetadata(new SolidColorBrush(Color.FromRgb(40, 139, 225))));
/// <summary>
/// 初始评分
/// </summary>
public string Score
{
get { return (string)GetValue(ScoreProperty); }
set { SetValue(ScoreProperty, value); }
}
public static readonly DependencyProperty ScoreProperty =
DependencyProperty.Register("Score", typeof(string), typeof(SummaryScoreResource),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty LoginIdProperty =
DependencyProperty.Register("LoginId", typeof(string), typeof(SummaryScoreResource),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty UserIdProperty =
DependencyProperty.Register("UserId", typeof(string), typeof(SummaryScoreResource),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty UserNameProperty =
DependencyProperty.Register("UserName", typeof(string), typeof(SummaryScoreResource), new FrameworkPropertyMetadata(string.Empty,new PropertyChangedCallback(ImageSourcePropertyChangedCallback)));
public static readonly DependencyProperty ImageSourceProperty =
DependencyProperty.Register("ImageSource", typeof(string), typeof(SummaryScoreResource),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty OrgNameProperty =
DependencyProperty.Register("OrgName", typeof(string), typeof(SummaryScoreResource),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.AffectsRender));
private static void ImageSourcePropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs arg)
{
}
}
}
SummaryScoreResource.xaml
<UserControl x:Class="Telewave.CompositeOperations.Views.IMViews.SummaryScoreResource"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Telewave.CompositeOperations.Views.IMViews"
xmlns:converters="clr-namespace:Telewave.CompositeOperations.Converters"
xmlns:customControl="clr-namespace:Telewave.CompositeOperations.CustomControl"
xmlns:IMViews="clr-namespace:Telewave.CompositeOperations.Views.IMViews"
mc:Ignorable="d"
d:DesignHeight="80" d:DesignWidth="900">
<UserControl.Resources>
<converters:StringToImageConverter x:Key="stringToImageConverter"/>
<Storyboard x:Key="showControl">
<DoubleAnimation Storyboard.TargetName="mainGrid"
Storyboard.TargetProperty="Height"
To="70" Duration="0:0:0.5">
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="mainGrid"
Storyboard.TargetProperty="Width"
To="740" Duration="0:0:0.5">
</DoubleAnimation>
</Storyboard>
<!--<Storyboard x:Key="closeControl">
<DoubleAnimation Storyboard.TargetName="Grid1"
Storyboard.TargetProperty="Height"
To="0" Duration="0:0:0.5">
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="Grid1"
Storyboard.TargetProperty="Width"
To="0" Duration="0:0:0.5">
</DoubleAnimation>
</Storyboard>-->
<GeometryGroup x:Key="clipGeometry" FillRule="Nonzero">
<EllipseGeometry RadiusX="30" RadiusY="30" Center="30,30"></EllipseGeometry>
</GeometryGroup>
<ControlTemplate x:Key="SummaryResourceTemplate" TargetType="{x:Type Button}">
<Grid x:Name="Grid1" Background="Transparent" >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="2"/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Source="{Binding Path=ImageSource,RelativeSource={RelativeSource AncestorType=IMViews:SummaryScoreResource},ConverterParameter=/headimg/defaultHeadImg.jpg,Converter={StaticResource stringToImageConverter}}"
Height="60" HorizontalAlignment="Center" VerticalAlignment="Center"
Name="image1"
Stretch="Fill"
Width="60" Margin="30,0,0,0"
Clip="{StaticResource ResourceKey=clipGeometry}"/>
<TextBlock Grid.Column="1" Margin="-50,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="14px" Foreground="{Binding DataContext.TextColor,RelativeSource={RelativeSource AncestorType=IMViews:SummaryScoreWindow}}" Text="{Binding Path=UserName,RelativeSource={RelativeSource AncestorType=IMViews:SummaryScoreResource}}">
</TextBlock>
<!--<TextBlock Grid.Column="2" Text="[网侦]" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="-95,0,0,0" >
</TextBlock>-->
<!--<customControl:NumericUpDown x:Name="numeric" Grid.Column="3" Increment="{ DataContext.Increment,ElementName=numeric}" MaxValue="{Binding DataContext.MaxValue,ElementName=numeric}" MinValue="{Binding DataContext.MinValue,ElementName=numeric}" Value="{Binding DataContext.Value,ElementName=numeric}"/>-->
<customControl:NumericUpDown x:Name="numeric" Grid.Column="3" HorizontalAlignment="Right" Value="{Binding DataContext.UsersScores,RelativeSource={RelativeSource AncestorType=IMViews:SummaryScoreResource}, UpdateSourceTrigger=PropertyChanged}"
UserId="{Binding DataContext.UserId,RelativeSource={RelativeSource AncestorType=IMViews:SummaryScoreResource}}"/>
</Grid>
<Border BorderBrush="{Binding DataContext.TextColor,RelativeSource={RelativeSource AncestorType=IMViews:SummaryScoreWindow}}" Background="{Binding DataContext.TextColor,RelativeSource={RelativeSource AncestorType=IMViews:SummaryScoreWindow}}" Margin="20,0,0,0" Grid.Row="1" />
</Grid>
<!--<ControlTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=IsMouseOver, ElementName=Grid1}" Value="True"></Condition>
</MultiDataTrigger.Conditions>
<Setter TargetName="Grid1" Property="Background" Value="LightBlue" />
</MultiDataTrigger>
</ControlTemplate.Triggers>-->
</ControlTemplate>
<Style TargetType="{x:Type Button}" x:Key="SummaryResourceStyle">
<Setter Property="Template" Value="{StaticResource SummaryResourceTemplate}" />
</Style>
</UserControl.Resources>
<UserControl.Triggers>
<EventTrigger RoutedEvent="IMViews:SummaryScoreResource.Loaded">
<BeginStoryboard Name="showQueryCanvasStoryboard2"
Storyboard="{StaticResource showControl}">
</BeginStoryboard>
</EventTrigger>
<!--弹回窗体--><!--
<EventTrigger RoutedEvent="IMViews:SummaryScoreResource.StartRemoveButton">
<BeginStoryboard Name="closeQueryCanvasStoryboard"
Storyboard="{StaticResource closeControl}">
</BeginStoryboard>
</EventTrigger>-->
</UserControl.Triggers>
<Grid x:Name="mainGrid" Width="600" Height="40">
<Button x:Name="btnControl" Style="{StaticResource SummaryResourceStyle}" ></Button>
</Grid>
</UserControl>
推荐阅读
-
WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展
-
Android自定义View简易折线图控件(二)
-
[WPF自定义控件库] 模仿UWP的ProgressRing
-
如何在双向绑定的Image控件上绘制自定义标记(wpf)
-
[WPF自定义控件库] 给WPF一个HyperlinkButton
-
[WPF自定义控件库]使用TextBlockHighlightSource强化高亮的功能,以及使用TypeConverter简化调用
-
WPF自定义实现IP地址输入控件
-
wpf 两个自定义控件
-
WPF的ListView控件自定义布局用法实例
-
WPF自定义控件之图片控件 AsyncImage