完整教程:WPF 程序用户权限模块利用MarkupExtension实现控制控件显示

news/2025/9/22 8:11:42/文章来源:https://www.cnblogs.com/tlnshuju/p/19104487

完整教程:WPF 程序用户权限模块利用MarkupExtension实现控制控件显示

2025-09-22 08:10  tlnshuju  阅读(0)  评论(0)    收藏  举报

工作记录

-------------------------------------------------------------------------------------------------------

MarkupExtension:XAML标记扩展

实现了什么作用:通过扩展标记将一种输入转化为另一种类型的输出

思路:

不直接设置控件的Visibility属性,利用一个标记扩展,传入一个权限值,然后拿这个权限值跟当前程序的用户权限对比,如果控件的权限值高于当前用户权限(比如控件的权限值是管理员,但是当前用户是普通用户),则返回Visibility.Collapsed,反之返回Visibility.Visible。

代码:

[MarkupExtensionReturnType(typeof(Visibility))]
public class PermissionVisibleExtension : MarkupExtension, IPermissionListener
{
private FrameworkElement targetObject;
private DependencyProperty targetProperty;
[ConstructorArgument("authority")]
public Authority Authority { get; set; }
public PermissionVisibleExtension()
{
}
public PermissionVisibleExtension(Authority authority)
{
Authority = authority;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
try
{
var providerValuetarget = (IProvideValueTarget)serviceProvider
.GetService(typeof(IProvideValueTarget));
//控件对象
targetObject = (FrameworkElement)providerValuetarget.TargetObject;
//元素布局事件
targetObject.Loaded += TargetObject_Loaded;
//元素删除事件
targetObject.Unloaded += TargetObject_Unloaded;
//标记的控件属性
targetProperty = (DependencyProperty)providerValuetarget.TargetProperty;
PermissionService.AddListener(this);
return PermissionService.Authority >= Authority ? Visibility.Visible : Visibility.Collapsed;
}
catch (Exception)
{
return Visibility.Collapsed;
}
}
private void TargetObject_Loaded(object sender, RoutedEventArgs e)
{
PermissionService.AddListener(this);
PermissionChanged(PermissionService.Authority);
}
private void TargetObject_Unloaded(object sender, RoutedEventArgs e)
{
PermissionService.RemoveListener(this);
}
public void PermissionChanged(Authority authority)
{
targetObject.SetCurrentValue(targetProperty, PermissionService.Authority >= Authority ? Visibility.Visible : Visibility.Collapsed);
}
}

其中IPermissionListener是提供了权限变更处理方法的接口:

public interface IPermissionListener
{
void PermissionChanged(Authority authority);
}

PermissionService是程序的权限管理类,保存着相关控件的扩展标记,提供了挂载方法:

private static readonly List listeners = new List();
public static void AddListener(IPermissionListener listener)
{
if (!listeners.Contains(listener))
{
listeners.Add(listener);
}
}
public static void RemoveListener(IPermissionListener listener)
{
if (listeners.Contains(listener))
{
listeners.Remove(listener);
}
}

当PermissionService类中的用户权限改变时,会遍历listeners 中的扩展,触发PermissionChanged方法:

private static void OnPermissionChanged()
{
foreach (var it in listeners)
{
//authority是当前类中的属性,表示用户权限
it.PermissionChanged(authority);
}
}

每个扩展中的PermissionChanged方法:

public void PermissionChanged(Authority authority)
{
targetObject.SetCurrentValue(targetProperty, PermissionService.Authority >= Authority ? Visibility.Visible : Visibility.Collapsed);
}

通过控件直接设置属性值实现改变控件可见状态;

前端写法:

Visibility="{view:PermissionVisible Authority=Expert}">

引用:笔记:WPF中MarkupExtension使用的IServiceProvider参数都有哪些_wpf iserviceprovider-CSDN博客

WPF基础之Binding解析_calcbinding-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/909196.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

私有外设总线PPB(Private Peripheral Bus) - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

enrichmcp 构建数据驱动mcp的框架

enrichmcp 构建数据驱动mcp的框架enrichmcp 构建数据驱动mcp的框架 包含的特性通过数据模型生成类型工具 处理实体关系 处理schema 发现 通过pydantic 模型进行input 以及output 校验 支持database,api,自定义逻辑 支…

完整教程:visual studio快捷键

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

AppSpider 7.5.020 for Windows - Web 应用程序安全测试

AppSpider 7.5.020 for Windows - Web 应用程序安全测试AppSpider 7.5.020 for Windows - Web 应用程序安全测试 Rapid7 Dynamic Application Security Testing (DAST) released Sep 2025 请访问原文链接:https://sys…

上周热点回顾(9.15

热点随笔:为什么不建议在 Docker 中跑 MySQL? (苏三说技术) C# 2025年6-9月TIOBE排名增长及未来展望 (张善友) 重要:Java25正式发布(长期支持版)! (磊哥|www.javacn.site) 刚刚 Java 25 炸裂发布!让 Java 再次…

“学术造神”何时休?

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087这个时代的学术圈,正在上演一场盛大的滑稽剧:实验室里产出的不再…

vLLM 核心机密:大模型推理引擎内部长啥样?

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087vLLM Offcie Hours #32 又披露了一批新技术。其中有两个比较特殊,…

华为销量下滑OV米荣迎来窗口期

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087一、华为手机销量阶段性下滑以下是全国全渠道销量份额(不包含智选…

【GitHub每日速递 250922】开源 AI 搜索引擎 Perplexica:本地大模型 + 多模式搜索,免费又强大!

原文: https://mp.weixin.qq.com/s/F7KwZlUd5OQg5CbAEbZGug MarkItDown:多格式文件转Markdown神器,助力LLM文本分析! markitdown 是一个将文件和办公文档转换为 Markdown 的工具。简单讲,它能帮你把 Word、Excel 等…

coze工作流实战——三分钟读一本名著

导航前言 作品展示 工作流展示 操作步骤 结语 参考前言2025年被行业认为是智能体(Agent)元年。过去几年,我们见证了AI 大模型的飞速发展,从只会简单回答问题,简单生成图文,到可以写代码,生成复杂视频,甚至可以…

大厂是怎么识别“高潜员工”的?

微信视频号:sph0RgSyDYV47z6快手号:4874645212抖音号:dy0so323fq2w小红书号:95619019828B站1:UID:3546863642871878B站2:UID: 3546955410049087大部分人都想当“高潜员工”,包括我,因为高潜员工意味着更好的机…

读人形机器人19后劳动经济

读人形机器人19后劳动经济1. 后劳动经济 1.1. 后劳动经济不仅仅是一个理论上的概念,它是AI、机器人技术和自动化技术融合的潜在现实 1.2. 核心设想是一个由机器人完成大部分工作的社会,使得人类劳动在经济生产中变得…

2025年最佳笔记本扩展坞评测:一站式提升工作站效率

本文深度评测2025年十大笔记本扩展坞,涵盖Thunderbolt 5技术、多显示器支持、数据传输速度对比及功率分配方案,帮助用户根据实际需求选择最适合的桌面扩展解决方案。10款最佳笔记本扩展坞(2025年):实测与评测 笔记…

论文查重项目

这个作业的GitHub地址 https://github.com/kakadomi/kakadomi这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Class34Grade23ComputerScience这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Cla…

我的第一个程序Hello,World!成功运行!

遇到了很多很多问题*JDK vs JRE,傻傻分不清,JDK才包含编译器javacOracle官网下载困难,转向下载Zulu OpenJDK(www.azul.com)配置环境变量后命令依然无效,在命令行输入javac -version不是内部或外部命令未输入完整路径…

Day05-1-C:\Users\Lenovo\Desktop\note\code\JavaSE\Basic\src\com\David\scanner-Demo01~05(简易计算器)

package com.David.scanner; import java.util.Scanner; public class Demo01 { public static void main(String[] args) { //创建一个扫描对象,用于接受键盘数据‘ Scanner scanner = new Scanner(System.in); Syst…

Day05-C:\Users\Lenovo\Desktop\note\code\JavaSE\Basic\src\com\David\struct-ifDemo01~03+shunxuDemo

Scanner Java.util.scanner Scanner s = new Scanner(System.in); Next一定要读取到有效字符才结束 对输入有效字符前的空白,next()方法会自动将其去掉 只有输入有效字符后才将其后面输入的空白作为分隔符或结束符 ne…

JS历理 优化login.js脚本2

const infoList = [];// 收集链接相关信息 const currentUrl = window.location.href || "未知链接"; const originUrl = window.location.origin || "未知源地址"; const pathname = window.loca…

Codeforces Round 1052 (Div. 2)

A. Equal Occurrences 题意:求\(a\)的一个最长子序列,使得每个数出现的次数相同。 记录每个数出现的次数,排序后从小到大枚举出现次数,那么比它多的数都可以选。点击查看代码 #include <bits/stdc++.h>using…

PatternMatcher-Pytorch

import os import torch import torch.nn as nn import torch._inductor.pattern_matcher as pm from torch._higher_order_ops.auto_functionalize import auto_functionalized from torch._inductor.compile_fx impo…