【黑马程序员】STL实战--演讲比赛管理系统

文章目录

  • 演讲比赛管理系统
    • 需求说明
      • 比赛规则
      • 程序功能
    • 创建管理类
      • 功能描述
      • 创建演讲比赛管理类
    • 菜单功能
      • 添加菜单成员函数声明
      • 菜单成员函数实现
      • 菜单功能测试
    • 退出功能
      • 添加退出功能声明
      • 退出成员函数实现
      • 退出功能测试
    • 演讲比赛功能
      • 功能分析
      • 创建选手类
      • 比赛
        • 成员属性添加
        • 初始化属性
        • 创建选手
        • 开始比赛成员函数
        • 抽签
        • 比赛过程
        • 显示晋级选手信息
        • 第二轮比赛
        • 保存分数
      • 查看记录
        • 从文件中加载记录
        • 将加载的记录进行展示
        • 功能实现
      • 清空记录

演讲比赛管理系统

需求说明

比赛规则

在这里插入图片描述

程序功能

在这里插入图片描述

创建管理类

功能描述

  • 提供菜单界面与用户交互

  • 对演讲比赛流程进行控制

  • 与文件的读写交互

创建演讲比赛管理类

  • 新建speechManager.hpp
#pragma once

#include <iostream>

using namespace std;

// 设计演讲比赛类
class SpeechManager {
public:
    // 构造函数    
    SpeechManager();
    // 析构函数   
    ~SpeechManager();
};
  • 新建speechManager.cpp
#include "speechManager.h"

// 构造函数
SpeechManager::SpeechManager() {

}

// 析构函数
SpeechManager::~SpeechManager() {

}

菜单功能

  • 功能描述:与用户的交互界面

添加菜单成员函数声明

  • speechManager.hpp中添加展示菜单成员函数声明
    // 菜单功能
    void showMenu();

菜单成员函数实现

  • speechManager.cpp中实现成员函数
// 菜单功能
void SpeechManager::showMenu() {
    cout << "*************************************" << endl;
    cout << "*******欢迎使用演讲比赛管理系统******" << endl;
    cout << "************1.开始演讲比较***********" << endl;
    cout << "************2.查看往届记录***********" << endl;
    cout << "************3.情况比赛记录***********" << endl;
    cout << "************4.退出比赛程序***********" << endl;
    cout << "*************************************" << endl;
}

菜单功能测试

  • 菜单功能测试,新建main.cpp
#include "speechManager.hpp"

int main() {
    SpeechManager sm;
    sm.showMenu();
}
  • 运行结果

在这里插入图片描述

退出功能

添加退出功能声明

  • speechManager.hpp中添加退出成员函数声明
    // 退出功能
    void Logout();

退出成员函数实现

  • speechManager.cpp中实现退出成员函数
// 退出功能
void SpeechManager::Logout() {
    cout << "即将退出系统,再见" << endl;
    exit(0);
}

退出功能测试

  • 退出功能测试,在main.cpp
#include "speechManager.hpp"

int main() {
    int choice;
    SpeechManager sm;
    while (true) {
        sm.showMenu();
        cout << "请输入你要使用的功能" << endl;
        cin >> choice;
        switch (choice) {
            case 1: //1.开始演讲比较
                break;
            case 2: //2.查看往届记录
                break;
            case 3: //3.清空比赛记录
                break;
            case 4: //4.退出比赛程序
                sm.Logout();
                break;
        }
    }
}
  • 运行结果

在这里插入图片描述

演讲比赛功能

功能分析

  • 比赛流程分析

    • 抽签–>开始演讲比赛–>显示第一轮比赛结果

    • 抽签–>开始演讲比赛–>显示前三名结果–>保存分数

创建选手类

  • 选手类中包括属性:选手姓名、分数

  • 新建speaker.hpp

#pragma once

#include <iostream>
#include <string>

using namespace std;

// 选手类
class Speaker {
public:
    string name;        // 姓名
    double score[2];    // 最多有两轮分数
};

比赛

成员属性添加
  • speechManager.hpp中添加
#include <vector>
#include <map>
#include "speaker.hpp"

// 类成员属性添加
    // 比赛选手容器 12人
    vector<int> v1;
    // 第一轮晋级选手容器 6人
    vector<int> v2;
    // 前三名容器 3人
    vector<int> v3;
    // 存放编号,以及队形的具体选手容器
    map<int, Speaker> mSpeaker;
    // 记录比赛轮数
    int mIndex;
初始化属性
  • speechManager.hpp中添加初始化属性成员函数声明
    // 初始化成员属性
    void initSpeech();
  • speechManager.cpp中实现初始化属性成员函数,并在构造函数中调用
// 初始化成员属性
void SpeechManager::initSpeech() {
    // 初始确保容器为空
    this->v1.clear();
    this->v2.clear();
    this->v3.clear();
    this->mSpeaker.clear();
    // 初始比赛轮数
    this->mIndex = 1;
}
创建选手
  • speechManager.hpp中添加创建选手成员函数声明
    // 创建选手
    void createSpeaker();
  • speechManager.cpp中实现创建选手成员函数,并在构造函数中调用
// 创建选手
void SpeechManager::createSpeaker() {
    string nameSeed = "ABCDEFGHIJKL";
    for (int i = 0; i < nameSeed.size(); i++) {
        string name = "选手";
        name += nameSeed[i];
        Speaker sp;

        sp.name = name;
        for (int i = 0; i < 2; i++) {
            sp.score[i] = 0;
        }
        // 12名选手编号
        this->v1.push_back(i + 10001);
        // 将选手放入到map中
        this->mSpeaker.insert(make_pair(i + 10001, sp));
    }
}
  • 创建成员测试
#include "speechManager.hpp"
#include "speaker.hpp"

int main() {
    SpeechManager sm;
    for (map<int, Speaker>::iterator it = sm.mSpeaker.begin(); it != sm.mSpeaker.end(); it++) {
        cout << it->first << "\t" << (it->second).name << "\t" << (it->second).score[0] << "\t" << (it->second).score[1]
             << endl;
    }
}
  • 运行结果

在这里插入图片描述

开始比赛成员函数
  • speechManager.hpp中添加开始比赛函数声明
    // 开始比赛
    void startSpeech();
  • speechManager.cpp中实现初始化属性成员函数,在开始比赛实现中先定义整体比赛的流程在慢慢实现,开始比赛功能在菜单中用户选择开始比赛时调用
// 开始比赛
void SpeechManager::startSpeech() {
    // 第一轮比赛
    // 1.抽签

    // 2.比赛

    // 3.显示晋级结果

    // 第二轮比赛
    // 1.抽签

    // 2.比赛

    // 3.显示最终结果

    // 4.保存分数
}
抽签
  • 抽签的本质就是打乱参赛者

  • speechManager.hpp中添加抽签函数声明

    // 抽签
    void drawLots();
  • speechManager.cpp中实现抽签函数,并在开始比赛的相应抽签流程位置调用
// 抽签
void SpeechManager::drawLots() {
    cout << "第" << this->mIndex << "轮比赛选手正在抽签" << endl;
    cout << "抽签后演讲顺序如下:" << endl;
    if (this->mIndex == 1) {
        // 第一轮抽签
        random_shuffle(this->v1.begin(), this->v1.end());
        printVector(this->v1);
    } else {
        // 第二轮抽签
        random_shuffle(this->v2.begin(), this->v2.end());
        printVector(this->v2);
    }
    cout << "------------------" << endl;
}
  • 运行结果

在这里插入图片描述

比赛过程
  • 比赛过程为最重要部分,需要好好理解消化

  • 比赛流程梳理

    • 准备临时容器存放小组成绩,每处理完一组

    • 判断是第几轮比赛,选择对应的比赛选手

    • 遍历当前比赛选手,让10个评委调用随机函数去给每个选手打分

    • 得到分数后放到双端队列deque中进行降序排列,然后弹出头尾实现,去掉最高分和去掉最低分操作

    • 计算每个比赛者的总分和平均分,将打分数据放在降序排列的临时map容器中,每6个人为一组取前3名

    • 将取得的前3名放到下一轮要比赛的选手容器中,清空临时存放成绩的容器s

  • speechManager.hpp中添加比赛函数声明

    // 比赛
    void game();
  • speechManager.cpp中实现比赛函数,并在开始比赛的相应比赛流程位置调用
// 比赛
void SpeechManager::game() {
    cout << "------------第" << this->mIndex << "轮比赛开始了------------" << endl;
    // 准备临时容器存放小组成绩
    multimap<double, int, greater<double> > groupScore;
    // 记录人员个数,6人一组
    int num = 0;
    // vSrc 当前比赛选手容器
    vector<int> vSrc;
    if (this->mIndex == 1) {
        // 给v1容器的人打分
        vSrc = v1;
    } else {
        // 给v2容器的人打分
        vSrc = v2;
    }
    // 遍历所有选手进行比赛
    for (vector<int>::const_iterator it = vSrc.begin(); it != vSrc.end(); it++) {
        num++;
        // 10个评委打分
        deque<double> d;
        for (int i = 0; i < 10; i++) {
            // 随机一个600~1000的数,然后在除10
            // .f表示是一个小数
            double score = (rand() % 401 + 600) / 10.f;
            // cout << score << " ";
            d.push_back(score);
        }
        // 对分数进行降序排列
        sort(d.begin(), d.end(), greater<double>());
        // 去掉一个最高分
        d.pop_front();
        // 去掉一个最低分
        d.pop_back();
        // 累加总分
        double sum = accumulate(d.begin(), d.end(), 0.0f);
        // 计算平均分
        double avg = sum / (double) d.size();
        // 打印平均分
        // cout << "编号:" << *it << " 姓名:" << this->mSpeaker[*it].name << " 平均分:" << avg << endl;
        // 将平均分放到map容器中
        this->mSpeaker[*it].score[this->mIndex - 1] = avg;
        // 将打分数据放入到临时小组容器中
        groupScore.insert(make_pair(avg, *it));
        // 每6人取前三名
        if (num % 6 == 0) {
            cout << "第" << num / 6 << "小组比赛名次:" << endl;
            for (multimap < double, int, greater < double > > ::iterator it = groupScore.begin();
                it != groupScore.end();
            it++) {
                cout << "编号:" << it->second << " 姓名:" << this->mSpeaker[it->second].name << " 分数:" << it->first
                     << endl;
            }
            // 获取前三名,放入下一轮容器中
            int count = 0;
            for (multimap < double, int, greater < double > > ::iterator it = groupScore.begin();
                it != groupScore.end() && count < 3;
            it++, count++) {
                if (this->mIndex == 1) {
                    v2.push_back(it->second);
                } else {
                    v3.push_back(it->second);
                }
            }
            // 取完一次需要清空一次小组容器
            groupScore.clear();
        }
    }
    cout << "----------第" << this->mIndex << "轮比赛完毕------------" << endl;
}
显示晋级选手信息
  • speechManager.hpp中添加显示晋级选手函数声明
    // 显示晋级结果
    void showScore();
  • speechManager.cpp中实现显示晋级选手函数,并在开始比赛的相应比赛流程位置调用
// 显示晋级结果
void SpeechManager::showScore() {
    cout << "第" << this->mIndex << "轮晋级选手信息如下: " << endl;
    vector<int> v;
    if (this->mIndex == 1) {
        v = v2;
    } else {
        v = v3;
    }
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
        cout << "编号:" << *it << " 姓名:" << this->mSpeaker[*it].name << " 分数:"
             << this->mSpeaker[*it].score[this->mIndex - 1] << endl;
    }
}
第二轮比赛
  • 第二轮比赛只需要将index++,然后在开始比赛函数的第二轮调用对应的封装好的函数即可

  • 开始比赛整体调用代码如下

// 开始比赛
void SpeechManager::startSpeech() {
    // 第一轮比赛
    // 1.抽签
    this->drawLots();
    // 2.比赛
    this->game();
    // 3.显示晋级结果
    this->showScore();
    this->mIndex++;
    // 第二轮比赛
    // 1.抽签
    this->drawLots();
    // 2.比赛
    this->game();
    // 3.显示最终结果
    this->showScore();
    // 4.保存分数
}
  • 运行结果

在这里插入图片描述
在这里插入图片描述

保存分数
  • speechManager.hpp中添加保存分数函数声明
    // 保存分数
    void saveScore();
  • speechManager.cpp中实现保存分数函数,并在开始比赛流程最后位置调用
void SpeechManager::saveScore() {
    ofstream ofs;
    // 以追加输出的方式打开文件, csv中内容需要以,号分割
    ofs.open("speech.csv", ios::out | ios::app);
    // 将每个人的数据保存到文件
    for (vector<int>::iterator it = v3.begin(); it != v3.end(); it++) {
        ofs << *it << ","
            << mSpeaker[*it].score[1] << ",";
    }
    ofs << endl;
    // 关闭文件
    ofs.close();
    cout << "记录已保存" << endl;
}

查看记录

从文件中加载记录
  • 文件不存在:提示直接返回

  • 文件存在但为空:先读一个字符看看是否读到了EOF

  • 文件存在不为空:

    • 先将读出的一个字符回写到文件中

    • 按行读取

    • 每读完一行按照逗号分割的方式将每一个编号和成绩的子字符串拿出来放入到临时vector中

    • 将一行vector中的内容放入往届成绩记录record容器中

将加载的记录进行展示
  • 遍历记录容器,将加载的内容一行一行的进行展示
功能实现
  • speechManager.hpp中添加对应的成员声明
    // 加载往届记录
    void loadRecord();

    // 查看往届记录
    void showRecord();

    // 记录比赛轮数
    int mIndex;
    // 文件是否为空标志
    bool fileIsEmpty;
    // 往届记录
    map<int, vector<string> > mRecord;
  • speechManager.cpp中实现相应的功能,在构造函数部分调用加载历史记录,在用户交互位置提供查看历史记录功能
// 查看分数
void SpeechManager::loadRecord() {
    ifstream ifs;
    ifs.open("speech.csv", ios::in);
    if (!ifs.is_open()) {
        // cout << "文件不存在" << endl;
        ifs.close();
        return;
    }
    // 文件存在
    // 文件被清空过的情况先读一个字符判断文件是否为空
    char ch;
    ifs >> ch;
    if (ifs.eof()) {
        cout << "文件为空" << endl;
        this->fileIsEmpty = true;
        ifs.close();
        return;
    }
    // 文件存在且不为空
    this->fileIsEmpty = false;
    // 将读取的字符放回
    ifs.putback(ch);
    string data;
    // index用来记录是第几届的数据,默认是第0届
    int index = 0;
    // 一行一行读
    while (ifs >> data) {
        // cout << data << endl;
        // 10005,83.6125,10007,82.7375,10008,80.725,
        // 存放每一届记录的前三编号和分数值
        vector <string> v;
        // pos查找逗号位置,默认为没有查到
        int pos = -1;
        // 从哪开始查找
        int start = 0;
        while (true) {
            // 从头开始查,
            pos = data.find(",", start);
            if (pos == -1) {
                break;
            }
            string tmp = data.substr(start, pos - start);
            v.push_back(tmp);
            // 下一次开始位置从上一个找到的逗号的下一个位置开始
            start = pos + 1;
        }
        // 将数据塞入往届成绩记录容器中
        this->mRecord.insert(make_pair(index, v));
        index++;
    }
    ifs.close();
}

// 查看往届记录
void SpeechManager::showRecord() {
    cout << " this->fileIsEmpty" << this->fileIsEmpty << endl;
    if (this->fileIsEmpty) {
        cout << "文件不存在或记录为空" << endl;
        return;
    }
    this->loadRecord();
    for (map < int, vector < string > > ::iterator it = this->mRecord.begin(); it != this->mRecord.end();
    it++) {
        cout << "第" << it->first + 1 << "届:" << endl;
        cout << "冠军编号:" << it->second[0] << " 分数:" << it->second[1] << endl;
        cout << "亚军编号:" << it->second[2] << " 分数:" << it->second[3] << endl;
        cout << "季军编号:" << it->second[4] << " 分数:" << it->second[5] << endl;
    }
}

清空记录

  • speechManager.hpp中添加清空记录函数成员声明
    // 清空记录
    void clearRecord();
  • speechManager.hpp中实现清空记录的功能,并在用户交互界面提供清空记录的功能调用
// 清空记录
void SpeechManager::clearRecord() {
    cout << "确认清空?" << endl;
    cout << "1.确认" << endl;
    cout << "2.返回" << endl;
    int select;
    cin >> select;
    if (select == 1) {
        // 清空文件:trunc模式,如果文件存在,则删除文件并重新创建
        ofstream ofs("speech.csv", ios::trunc);
        ofs.close();
        // 初始化属性
        this->initSpeech();
        // 创建选手
        this->createSpeaker();
        // 加载往届成绩
        this->loadRecord();
        cout << "清空成功" << endl;
    }
}

完整项目位置

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

KVM技术原理及安装KVM并且在KVM里面安装RHEL8

目录 一、kvm原理 1..1虚拟化概念 1.2 虚拟化产生背景 1.3虚拟化架构 1.4主流的虚拟化技术 1.5阐述个人对虚拟化技术的几种分类认知 二、安装KVM并且在KVM里面安装RHEL8 2.1在RHEL8主机上安装KVM 2.2安装完成后&#xff0c;使用virt-manager命令打开虚拟机管理图形界面…

Python错题集-8:AttributeError(找不到对应的对象的属性)

1问题描述 AttributeError: AxesSubplot object has no attribute arc 2代码详情 import matplotlib.pyplot as plt# 创建一个新的图形和坐标轴 fig, ax plt.subplots()# 定义弧线的参数 center (0.5, 0.5) # 圆心坐标 (x, y) width 1.0 # 半径 height 0.5 # 半径 ang…

Charles抓包工具使用

Charles简介 Charles是一款基于HTTP协议的代理服务器和HTTP监视器&#xff0c;通过将自己设置为电脑或浏览器的网络访问代理&#xff0c;能够截取请求和请求结果&#xff0c;从而达到分析抓包的目的。它允许开发者查看所有连接互联网的HTTP通信&#xff0c;包括请求、响应和HTT…

【漏洞复现】Linksys E2000 position.js 身份验证绕过漏洞(CVE-2024-27497)

0x01 产品简介 Linksys E2000是一款由思科&#xff08;Cisco&#xff09;品牌推出的无线路由器&#xff0c;它是一款支持2.4GHz和5GHz双频段的无线路由器&#xff0c;用户可以避开拥挤的2.4GHz频段&#xff0c;独自享受5GHz频段的高速无线生活。 0x02 漏洞概述 Linksys E200…

JAVA虚拟机、Dalvik虚拟机和ART虚拟机简要对比

1、什么是JVM&#xff1f; JVM本质上就是一个软件&#xff0c;是计算机硬件的一层软件抽象&#xff0c;在这之上才能够运行Java程序&#xff0c;JAVA在编译后会生成类似于汇编语言的JVM字节码&#xff0c;与C语言编译后产生的汇编语言不同的是&#xff0c;C编译成的汇编语言会…

hadoop集群部署教程

文章目录 前言一、相关介绍1. 配置文件位置1.1 只读默认配置文件1.2 可修改配置文件1.3 相关环境变量配置文件 二、安装准备1. 准备centos2. 配置集群免密登录3. 部署规划4. 安装条件5. 安装jdk 三、安装hadoop1. 下载并解压hadoop2. 设置环境变量2.1 设置hadoop安装目录环境变…

Diddler抓包工具——学习笔记

F12抓包 302【重定向】&#xff1a;当你发送了一个请求之后&#xff0c;那么这个请求重定向到了另外的资源 跳转和重定向的区别&#xff1a; 跳转是会把数据传到新的地址 重定向不会把新的数据传到新的地址 使用F12抓包时一定要打开Preserve Log开关&#xff0c;作用是保留…

【CSP试题回顾】202009-1-称检测点查询

CSP-202009-1-称检测点查询 解题代码 #include <iostream> #include <vector> #include <cmath> #include <algorithm> using namespace std;int n, X, Y, x, y; struct MyDistance {int index;int dis; }; vector<MyDistance>list; bool cmp(…

福州·名城银河湾220㎡现代简约风装修案例分享。福州中宅装饰,福州装修

以手作维度构境, 跳脱约定成俗的风格, 转化内外地域分际, 于静谧中凝聚丰厚的美学能量, 谦虚且沉默以对。 平面设计图 项目信息 项目名称 | 名城银河湾 设计地址 | 福建福州 项目面积 | 220㎡ 项目户型 | 5室2厅2厨3卫 设计风格 | 现代轻奢 首席设计师丨欧阳光玉 中…

C#,老鼠迷宫问题的回溯法求解(Rat in a Maze)算法与源代码

1 老鼠迷宫问题 迷宫中的老鼠&#xff0c;作为另一个可以使用回溯解决的示例问题。 迷宫以块的NN二进制矩阵给出&#xff0c;其中源块是最左上方的块&#xff0c;即迷宫[0][0]&#xff0c;目标块是最右下方的块&#xff0c;即迷宫[N-1][N-1]。老鼠从源头开始&#xff0c;必须…

《C缺陷和陷阱》-笔记(2)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 文章目录 前言 一、理解函数声明 1.(*(void(*)( ))0)( ); 2.signal 函数接受两个参数&#xff1a; 3.使用typedef 简化函数声明&#xff1a; 二、运算符的优先级…

C/C++实现代码雨效果

C/C实现代码雨效果 目录 C/C实现代码雨效果 说明使用的库说明测试代码效果图 说明 最近整理电脑资料&#xff0c;翻出了以前写的代码&#xff0c;顺便整理一下到博客上&#xff0c;当做一次备份记录 先看看静态效果 需要分为以下步骤实现 生成代码串把代码串绘制到窗口中使…

差分约束

&#xff08;1&#xff09;求不等式组的可行解 源点需满足的条件&#xff1a;从源点出发&#xff0c;一定可以到达所有的边 求最短路 步骤&#xff1a;1.先将每个不等式xi<xj ck&#xff0c;转化成一条从xj走到xi&#xff0c;长度为ck的一条边 2.找一个超级源点&#xff0c…

CentOS7 利用remi yum源安装php8.1

目录 前言remi yum源remi yum源 支持的操作系统remi yum源 支持的php版本 安装epel源安装remi源安装 php8.1查看php版本查看php-fpm服务启动php-fpm服务查看php-fpm服务运行状态查看php-fpm服务占用的端口查看 php8.1 相关的应用 前言 CentOS Linux release 7.9.2009 (Core) …

【粉丝福利第四期】:《低代码平台开发实践:基于React》(文末送书)

文章目录 前言一、React与低代码平台的结合优势二、基于React的低代码平台开发挑战三、基于React的低代码平台开发实践四、未来展望《低代码平台开发实践&#xff1a;基于React》五、粉丝福利 前言 随着数字化转型的深入&#xff0c;企业对应用开发的效率和灵活性要求越来越高…

分销商城微信小程序:用户粘性增强,促进复购率提升

在数字化浪潮的推动下&#xff0c;微信小程序作为一种轻便、高效的移动应用形式&#xff0c;正成为越来越多企业开展电商业务的重要平台。而分销商城微信小程序的出现&#xff0c;更是为企业带来了前所未有的机遇。通过分销商城微信小程序&#xff0c;企业不仅能够拓宽销售渠道…

Double和Float类

Double类 功能&#xff1a;实现对Double基本型数据的类包 构造方法&#xff1a; (double num) double Value()方法&#xff1a;返回对象中的double型数据。 Float类 功能&#xff1a;实现对float基本型数据的类包装。 构造方法&#xff1a; (float num) Float Value()方法…

户用光伏创新技术,引领光伏时代进步

户用光伏近几年由于国家政策支持力度加大&#xff0c;技术也在快速发展&#xff0c;成功引领我国光伏时代的进步&#xff0c;掌握核心技术必将在新能源市场中抢占主导地位&#xff01; 一、制造方面 1.高效低成本晶硅太阳能电池表界面制造技术 这项技术主要涉及晶硅太阳能电池…

CraxsRat7.4 安卓手机远程管理软件

CRAXSRAT 7.4 最新视频 https://v.douyin.com/iFjrw2aD/ 官方网站下载 http://craxsrat.cn/ 不要问我是谁&#xff0c;我是活雷锋。 http://craxsrat.cn/ CraxsRat CraxsRat7 CraxsRat7.1 CraxsRat7.2 CraxsRat7.3 CraxsRat7.4

WPF 窗口添加投影效果Effect

BlurRadius&#xff1a;阴影半径 Color&#xff1a;颜色 Direction&#xff1a;投影方向 ShadowDepth&#xff1a;投影的深度 <Window.Effect><DropShadowEffect BlurRadius"10" Color"#FF858484" Direction"300" ShadowDepth&quo…
最新文章