public virtual T Get<T>(string key, T defaultValue)

本文介绍了一种通用的HTTP请求参数解析方法,该方法能够根据不同类型的请求参数返回相应的值,支持int和string类型,并提供了默认值处理及类型转换错误时的回退策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用如下:

 

int  id = Get < int > ( " id " , - 1 );

string  name = Get < string > ( " name " , "" );

 

 

函数代码如下:

复制代码
public   virtual  T Get < T > ( string  key, T defaultValue)
        {
            
if  (Request[key]  ==   null ) {  return  defaultValue; }
            
object  result;
            
if  ( typeof (T).Name  ==   " Int32 " )
            {
                
int  _result  =   0 ;
                
if  ( ! int .TryParse(Request[key],  out  _result))
                {
                    
return  defaultValue;
                }
                result 
=  _result;
            }
            
else
            {
                result 
=  Request[key].Trim();
            }
            
return  (T)result;
        }

// 只能把object类型转T,其它类型都报错
复制代码

#pragma once #include <iostream> #include "pugixml.hpp" #include <vector> #include <unordered_map> #include <memory> #include <mutex> extern pugi::xml_document doc; //存储配置文件信息 extern bool parse_config(); //上下文管理 struct Context { std::mutex mtx; public: void set(const std::string& key, const std::string& value) { ContextMap[key] = value; } void safeMethod() { // 安全操作... } std::string get(const std::string& key)const { auto it = ContextMap.find(key); if (it == ContextMap.end()) { throw std::runtime_error("key : " + key + " not found"); } return it->second; } private: std::unordered_map<std::string, std::string> ContextMap; }; #pragma once #include "Context.h" #include <iostream> class any { public : any() = default; ~any() = default; //any禁止左值引用的拷贝和左值引用的赋值 any(const any&) = delete; any& operator=(const any&) = delete; //any允许右值引用的拷贝和右值引用的赋值 any(any&&) = default; any& operator=(any&&) = default; //any的构造函数写成模板,传过来的任意数据型通过基指针传给派生 template <typename T> any(T data) : base_(std::make_unique<Derive<T>>(data)) {}; //提取出any对象中的data_数据 template <typename T> T cast_() { //cast_函数功能:从base_指向的Derive对象取出data_ //基指针 转为 派生指针。需要确保该基指针确实指向某派生 //get()方法为库函数,旨在获取智能指针中的裸指针 Derive<T>* pd = dynamic_cast<Derive<T*>>(base_.get()); if (pd == nullptr) { throw "cast_ : 请提供正确的型!"; } return pd->data_; } private : //基型 class Base { virtual ~Base() = default; }; //派生型,定于为模板才可以接收任意数据型 template <typename T> class Derive : public Base { public: Derive(T data) : data_(data) {}; T data_;//存放实际接受的数据 }; private : std::unique_ptr<Base> base_; }; //组件基 class Component { public: virtual ~Component() = default; virtual bool execute(Context& ctx) = 0; }; using ComponentPtr = std::shared_ptr<Component>; #pragma once #include "component.hpp" #include <unordered_map> #include <mutex> //组件注册表 class ComponentRegistry { public: static ComponentRegistry& instance() { static ComponentRegistry registry; return registry; } template <typename T> void registerComponent(const std::string& name) { std::lock_guard<std::mutex> lock(m_mutex); components()[name] = std::make_unique<T>(); } Component* getComponent(const std::string& name) { std::lock_guard<std::mutex> lock(m_mutex); auto it = components().find(name); return (it != components().end()) ? it->second.get() : nullptr; } // 禁止拷贝和赋值 ComponentRegistry(const ComponentRegistry&) = delete; ComponentRegistry& operator=(const ComponentRegistry&) = delete; private: // 私有构造函数(单例模式) ComponentRegistry() = default; ~ComponentRegistry() = default; // 存储组件的线程安全容器 using ComponentMap = std::unordered_map<std::string, std::unique_ptr<Component>>; ComponentMap& components() { static ComponentMap instance; return instance; } std::mutex m_mutex; // 互斥锁 }; #pragma once #include "Context.h" //EL表达式基 class ExpressionNode { public: virtual ~ExpressionNode() = default; virtual void execute(Context& ctx) = 0; }; #include "IfNode.h" IfNode::IfNode(std::string name,std::unique_ptr<ExpressionNode> thenBranch, std::unique_ptr<ExpressionNode> elseBranch) :thenBranch(std::move(thenBranch)), elseBranch(std::move(elseBranch)) { component = ComponentRegistry::instance().getComponent(name); if (!component) { std::cerr << "no component ! " << std::endl; } } void IfNode::execute(Context& ctx) { if (component->execute(ctx)) { thenBranch->execute(ctx); } else { elseBranch->execute(ctx); } } #include "SingleNode.h" SingleNode::SingleNode(const std::string& name) { component = ComponentRegistry::instance().getComponent(name); if (!component) { std::cerr << "no component ! " << std::endl; } } void SingleNode::execute(Context& ctx) { component->execute(ctx); } #include "ThenNode.h" ThenNode::ThenNode(std::vector<std::unique_ptr<ExpressionNode>>&& nodes) :children(std::move(nodes)) { } void ThenNode::execute(Context& ctx) { for (auto& child : children) { child->execute(ctx); } } #include "WhenNode.h" WhenNode::WhenNode(std::vector<std::unique_ptr<ExpressionNode>> children) : children_(std::move(children)) { } void WhenNode::execute(Context& ctx) { std::vector<std::future<void>> futures; // 并行执行所有子节点 for (auto& child : children_) { futures.emplace_back(std::async(std::launch::async, [&] { child->execute(ctx); })); } // 等待所有任务完成 for (auto& future : futures) { future.get(); } } #include "Parser.h" #include <algorithm> #include <stdexcept> #include <sstream> #include <iostream> #include"SingleNode.h" #include"Context.h" #include"IfNode.h" #include"ThenNode.h" #include"WhenNode.h" #include"AndNode.h" #include"NotNode.h" #include"OrNode.h" using namespace std; unique_ptr<ExpressionNode> Parser::parse(const string& expr) { string cleaned = trim(expr.substr(expr.find('(') + 1, expr.rfind(')') - expr.find('(') - 1)); return parseExpression(cleaned); } unique_ptr<ExpressionNode> Parser::parseSingleNode(const string& expr) { if (expr.find("THEN(") != 0 && expr.find("IF(") != 0 && expr.find("WHEN(") != 0 && expr.find("AND(") != 0 && expr.find("OR(") != 0 && expr.find("NOT(") != 0) { return make_unique<SingleNode>(expr); } return parseExpression(expr); } unique_ptr<ExpressionNode> Parser::parseIfExpression(const string& expr) { size_t comma1 = findMatchingBracket(expr, 0); string condition = trim(expr.substr(0, comma1)); size_t comma2 = findMatchingBracket(expr, comma1 + 1); string thenPart = trim(expr.substr(comma1 + 1, comma2 - comma1 - 1)); string elsePart = trim(expr.substr(comma2 + 1)); auto conditionNode = parseLogicalExpression(condition); return make_unique<IfNode>(condition, move(conditionNode), elsePart.empty() ? nullptr : parseExpression(elsePart)); } unique_ptr<ExpressionNode> Parser::parseThenExpression(const string& expr) { vector<unique_ptr<ExpressionNode>> children; size_t pos = 0; while (pos < expr.size()) { size_t end = findMatchingBracket(expr, pos); string item = expr.substr(pos, end - pos); children.push_back(parseExpression(trim(item))); pos = (end == string::npos) ? expr.size() : end + 1; } return make_unique<ThenNode>(move(children)); } unique_ptr<ExpressionNode> Parser::parseWhenExpression(const string& expr) { vector<unique_ptr<ExpressionNode>> children; auto parts = splitComponents(expr); for (const auto& part : parts) { children.push_back(parseExpression(trim(part))); } return make_unique<WhenNode>(move(children)); } vector<string> Parser::splitComponents(const string& expr) { vector<string> parts; int bracketCount = 0; size_t start = 0; for (size_t i = 0; i < expr.size(); ++i) { char c = expr[i]; if (c == '(') { bracketCount++; } else if (c == ')') { bracketCount--; } else if (c == ',' && bracketCount == 0) { string part = expr.substr(start, i - start); parts.push_back(trim(part)); start = i + 1; } } if (start < expr.size()) { string lastPart = expr.substr(start); parts.push_back(trim(lastPart)); } return parts; } unique_ptr<ExpressionNode> Parser::parseExpression(const string& expr) { try { string trimmed = trim(expr); if (trimmed.empty()) { throw runtime_error("Empty expression"); } if (startsWith(trimmed, "THEN(")) { return parseThenExpression(trimmed.substr(5, trimmed.size() - 6)); } if (startsWith(trimmed, "IF(")) { return parseIfExpression(trimmed.substr(3, trimmed.size() - 4)); } if (startsWith(trimmed, "WHEN(") || startsWith(trimmed, "PAR(")) { return parseWhenExpression(trimmed.substr(5, trimmed.size() - 6)); } if (startsWith(trimmed, "AND(")) { return parseAndExpression(trimmed.substr(4, trimmed.size() - 5)); } if (startsWith(trimmed, "OR(")) { return parseOrExpression(trimmed.substr(3, trimmed.size() - 4)); } if (startsWith(trimmed, "NOT(")) { return parseNotExpression(trimmed.substr(4, trimmed.size() - 5)); } return parseSingleNode(trimmed); } catch (const exception& e) { cerr << "Parse EL error: " << e.what() << endl; throw; } } // 新增逻辑表达式解析方法 unique_ptr<ExpressionNode> Parser::parseLogicalExpression(const string& expr) { string trimmed = trim(expr); if (startsWith(trimmed, "AND(")) { return parseAndExpression(trimmed.substr(4, trimmed.size() - 5)); } if (startsWith(trimmed, "OR(")) { return parseOrExpression(trimmed.substr(3, trimmed.size() - 4)); } if (startsWith(trimmed, "NOT(")) { return parseNotExpression(trimmed.substr(4, trimmed.size() - 5)); } return parseSingleNode(trimmed); } unique_ptr<ExpressionNode> Parser::parseAndExpression(const string& expr) { auto parts = splitComponents(expr); vector<unique_ptr<ExpressionNode>> children; for (const auto& part : parts) { children.push_back(parseLogicalExpression(trim(part))); } return make_unique<AndNode>(move(children)); } unique_ptr<ExpressionNode> Parser::parseOrExpression(const string& expr) { auto parts = splitComponents(expr); vector<unique_ptr<ExpressionNode>> children; for (const auto& part : parts) { children.push_back(parseLogicalExpression(trim(part))); } return make_unique<OrNode>(move(children)); } unique_ptr<ExpressionNode> Parser::parseNotExpression(const string& expr) { // 确保NOT表达式只有一个参数 auto parts = splitComponents(expr); if (parts.size() != 1) { throw runtime_error("NOT expression requires exactly one argument"); } return make_unique<NotNode>(parseLogicalExpression(trim(parts[0]))); } // 辅助函数 bool Parser::startsWith(const string& str, const string& prefix) { return str.compare(0, prefix.length(), prefix) == 0; } size_t Parser::findMatchingBracket(const string& expr, size_t start) { int balance = 0; for (size_t i = start; i < expr.size(); ++i) { if (expr[i] == '(') balance++; else if (expr[i] == ')') balance--; else if (expr[i] == ',' && balance == 0) { return i; } } return string::npos; } string Parser::trim(const string& s) { size_t start = s.find_first_not_of(" \t\n\r"); size_t end = s.find_last_not_of(" \t\n\r"); return (start == string::npos) ? "" : s.substr(start, end - start + 1); } 提供了与或非表达式,就是AND,OR,NOT表达式。通过之前的几小章,应该可以知道,有些编排需要返回一个布尔值,比如条件编排: <chain name="chain1"> IF(x, a, b); </chain> 其中x组件应该为布尔组件,返回的是一个布尔值。但是如果这个布尔值并不是由一个组件决定的,而是由多个组件决定的呢。这里就可以用与或非表达式了。假设这里的条件是要由x和y共同决定,利用与或非表达式中的AND: <chain name="chain1"> IF(AND(x,y), a, b); </chain> 上述AND的意思是,如果x和y都为true,则为真,会执行组件a,如果x和y有一个为false,则执行b。 AND里面可以有多个布尔组件或者与或非表达式。同理,这里也可以用OR来表示: <chain name="chain1"> IF(OR(x,y), a, b); </chain> 上述OR的意思是,只要x和y中的一个为true,则为真,否则为假。OR里面可以有多个组件或者与或非表达式。NOT就是非的意思,比如: <chain name="chain1"> IF(NOT(x), a, b); </chain> 如果x返回true,则经过非运算后,为假,执行b,如果x返回false,则经过非运算后,为真,执行a。NOT里面只能有一个布尔组件或者与或非表达式。 怎样修改parse并增加新的弄得文件内容
07-08
<Window x:Class="FengJing.Views.OtherView.PlantList" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:FengJing.Views.OtherView" mc:Ignorable="d" Title="苗木信息管理" Height="600" Width="1200" WindowStartupLocation="CenterScreen"> <Window.Resources> <!-- 按钮样式 --> <Style TargetType="Button" x:Key="ActionButton"> <Setter Property="Margin" Value="2"/> <Setter Property="Padding" Value="5,2"/> <Setter Property="MinWidth" Value="60"/> </Style> <!-- 搜索框样式 --> <Style TargetType="TextBox" x:Key="SearchBox"> <Setter Property="Margin" Value="5"/> <Setter Property="Padding" Value="5"/> <Setter Property="MinWidth" Value="200"/> </Style> <!-- 数据网格样式 --> <Style TargetType="DataGrid"> <Setter Property="Margin" Value="10"/> <Setter Property="AutoGenerateColumns" Value="False"/> <Setter Property="CanUserAddRows" Value="False"/> <Setter Property="CanUserDeleteRows" Value="False"/> <Setter Property="SelectionMode" Value="Single"/> <Setter Property="IsReadOnly" Value="True"/> <Setter Property="RowHeaderWidth" Value="0"/> <Setter Property="VerticalScrollBarVisibility" Value="Auto"/> <Setter Property="HorizontalScrollBarVisibility" Value="Auto"/> </Style> <!-- 数字列样式 --> <Style TargetType="DataGridTextColumn"> <Setter Property="ElementStyle"> <Setter.Value> <Style TargetType="TextBlock"> <Setter Property="HorizontalAlignment" Value="Right"/> <Setter Property="Margin" Value="0,0,10,0"/> </Style> </Setter.Value> </Setter> </Style> <!-- 新增:搜索区域折叠/展开动画 --> <Storyboard x:Key="ExpandSearchPanel" Duration="0:0:0.3"> <DoubleAnimation Storyboard.TargetProperty="Height" From="0" To="{Binding ElementName=SearchPanel, Path=DesiredHeight}" DecelerationRatio="0.9"/> </Storyboard> <Storyboard x:Key="CollapseSearchPanel" Duration="0:0:0.3"> <DoubleAnimation Storyboard.TargetProperty="Height" From="{Binding ElementName=SearchPanel, Path=ActualHeight}" To="0" AccelerationRatio="0.9"/> </Storyboard> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <!-- 状态栏 --> </Grid.RowDefinitions> <!-- 工具栏 --> <StackPanel Orientation="Horizontal" Margin="10" Grid.Row="0"> <Button Content="添加苗木" Command="{Binding AddPlantCommand}" Style="{StaticResource ActionButton}" Background="#4CAF50" Foreground="White" Click="Button_Click_Create" Height="33.24"/> <Button Content="刷新列表" Command="{Binding RefreshCommand}" Style="{StaticResource ActionButton}" Height="33.24"/> <Button x:Name="btnPreciseSearch" Content="精确搜索" Click="ToggleSearchPanel" Style="{StaticResource ActionButton}" Margin="5,0,0,0" Height="33.24" Background="#2196F3" Foreground="White"/> <Button Content="导入苗木列表" Command="{Binding ImportCommand}" Style="{StaticResource ActionButton}" Margin="5,0,0,0" Height="33.24" Background="#2196F3" Foreground="White"/> </StackPanel> <!-- 精确搜索条件区域 - 初始折叠 --> <Border x:Name="SearchPanel" Grid.Row="1" Margin="10,0,10,10" Padding="10" BorderBrush="#CCCCCC" BorderThickness="1" Background="#F5F5F5" Height="0" VerticalAlignment="Top"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <!-- 第一行 --> <TextBlock Text="苗木名称:" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Margin="5"/> <TextBox Text="{Binding SearchName, UpdateSourceTrigger=PropertyChanged}" Grid.Row="0" Grid.Column="1" Margin="5" MinWidth="100"/> <TextBlock Text="型:" Grid.Row="0" Grid.Column="2" VerticalAlignment="Center" Margin="5"/> <TextBox Text="{Binding SearchType, UpdateSourceTrigger=PropertyChanged}" Grid.Row="0" Grid.Column="3" Margin="5" MinWidth="100"/> <TextBlock Text="颜色:" Grid.Row="0" Grid.Column="4" VerticalAlignment="Center" Margin="5"/> <TextBox Text="{Binding SearchColor, UpdateSourceTrigger=PropertyChanged}" Grid.Row="0" Grid.Column="5" Margin="5" MinWidth="100"/> <TextBlock Text="单位:" Grid.Row="0" Grid.Column="6" VerticalAlignment="Center" Margin="5"/> <TextBox Text="{Binding SearchUnit, UpdateSourceTrigger=PropertyChanged}" Grid.Row="0" Grid.Column="7" Margin="5" MinWidth="100"/> <!-- 第二行 --> <TextBlock Text="适生地区:" Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" Margin="5"/> <TextBox Text="{Binding SearchSuitableRegion, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="1" Margin="5" MinWidth="100"/> <TextBlock Text="生长习性:" Grid.Row="1" Grid.Column="2" VerticalAlignment="Center" Margin="5"/> <TextBox Text="{Binding SearchHabit, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="3" Margin="5" MinWidth="100"/> <TextBlock Text="耐湿耐旱性:" Grid.Row="1" Grid.Column="4" VerticalAlignment="Center" Margin="5"/> <TextBox Text="{Binding SearchWetDroughtTolerance, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="5" Margin="5" MinWidth="100"/> <TextBlock Text="是否海绵:" Grid.Row="1" Grid.Column="6" VerticalAlignment="Center" Margin="5"/> <TextBox Text="{Binding SearchIsSpongePlant, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="7" Margin="5" MinWidth="100"/> <!-- 第三行 --> <TextBlock Text="常绿落叶性:" Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" Margin="5"/> <TextBox Text="{Binding SearchEvergreenDeciduous, UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" Grid.Column="1" Margin="5" MinWidth="100"/> <TextBlock Text="观赏价值:" Grid.Row="2" Grid.Column="2" VerticalAlignment="Center" Margin="5"/> <TextBox Text="{Binding SearchOrnamentalValue, UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" Grid.Column="3" Margin="5" MinWidth="100"/> <TextBlock Text="色叶期:" Grid.Row="2" Grid.Column="4" VerticalAlignment="Center" Margin="5"/> <TextBox Text="{Binding SearchColorPeriod, UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" Grid.Column="5" Margin="5" MinWidth="100"/> <TextBlock Text="胸径/地径(cm):" Grid.Row="2" Grid.Column="6" VerticalAlignment="Center" Margin="5"/> <TextBox Text="{Binding SearchDiameter, UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" Grid.Column="7" Margin="5" MinWidth="100"/> <!-- 第四行 --> <TextBlock Text="高度(cm):" Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" Margin="5"/> <TextBox Text="{Binding SearchHeight, UpdateSourceTrigger=PropertyChanged}" Grid.Row="3" Grid.Column="1" Margin="5" MinWidth="100"/> <TextBlock Text="冠幅(cm):" Grid.Row="3" Grid.Column="2" VerticalAlignment="Center" Margin="5"/> <TextBox Text="{Binding SearchCrownWidth, UpdateSourceTrigger=PropertyChanged}" Grid.Row="3" Grid.Column="3" Margin="5" MinWidth="100"/> <TextBlock Text="信息价():" Grid.Row="3" Grid.Column="4" VerticalAlignment="Center" Margin="5"/> <TextBox Text="{Binding SearchPrice, UpdateSourceTrigger=PropertyChanged}" Grid.Row="3" Grid.Column="5" Margin="5" MinWidth="100"/> <StackPanel Orientation="Horizontal" Grid.Row="3" Grid.Column="7" HorizontalAlignment="Right"> <Button Content="搜索" Command="{Binding SearchCommand}" Style="{StaticResource ActionButton}" Margin="5" Width="80" Background="#4CAF50" Foreground="White"/> <Button Content="清除条件" Command="{Binding ClearSearchCommand}" Style="{StaticResource ActionButton}" Margin="5" Width="80"/> </StackPanel> </Grid> </Border> <!-- 数据网格 --> <DataGrid x:Name="PlantDataGrid" ItemsSource="{Binding Plants}" Grid.Row="1" SelectedItem="{Binding SelectedPlant}"> <DataGrid.Columns> <DataGridTextColumn Header="序号" Binding="{Binding Id}" Width="60"/> <DataGridTextColumn Header="苗木名称" Binding="{Binding Name}" Width="100"/> <DataGridTextColumn Header="型" Binding="{Binding Type}" Width="60"/> <DataGridTextColumn Header="颜色" Binding="{Binding Color}" Width="60"/> <DataGridTextColumn Header="单位" Binding="{Binding Unit}" Width="60"/> <DataGridTextColumn Header="适生地区" Binding="{Binding SuitableRegion}" Width="120"/> <DataGridTextColumn Header="生长习性" Binding="{Binding Habit}" Width="120"/> <DataGridTextColumn Header="奈湿奈旱性" Binding="{Binding WetDroughtTolerance}" Width="70"/> <DataGridTextColumn Header="是否海绵" Binding="{Binding IsSpongePlant}" Width="70"/> <DataGridTextColumn Header="常绿落叶性" Binding="{Binding EvergreenDeciduous}" Width="80"/> <DataGridTextColumn Header="观赏价值" Binding="{Binding OrnamentalValue}" Width="80"/> <DataGridTextColumn Header="色叶期" Binding="{Binding ColorPeriod}" Width="70"/> <DataGridTextColumn Header="胸径/地径(cm)" Binding="{Binding Diameter, StringFormat={}{0:F2}}" Width="100"/> <DataGridTextColumn Header="高度(cm)" Binding="{Binding Height, StringFormat={}{0:F2}}" Width="80"/> <DataGridTextColumn Header="冠幅(cm)" Binding="{Binding CrownWidth, StringFormat={}{0:F2}}" Width="80"/> <DataGridTextColumn Header="信息价()" Binding="{Binding Price, StringFormat={}{0:N2}}" Width="100"/> <DataGridTextColumn Header="创建时间" Binding="{Binding CreateAt, StringFormat=yyyy-MM-dd HH:mm:ss}" Width="130"/> <DataGridTextColumn Header="更新时间" Binding="{Binding LastUpdatedAt, StringFormat=yyyy-MM-dd HH:mm:ss}" Width="130"/> <!-- 操作列 --> <DataGridTemplateColumn Header="操作" Width="190"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <!-- 新增的查看图片按钮 --> <Button Content="查看图片" Command="{Binding DataContext.ViewImageCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}" CommandParameter="{Binding}" Style="{StaticResource ActionButton}" Background="#4CAF50" Foreground="White" Margin="0,0,5,0"/> <Button Content="编辑" Command="{Binding DataContext.EditPlantCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}" CommandParameter="{Binding}" Style="{StaticResource ActionButton}" Background="#2196F3" Foreground="White"/> <Button Content="删除" Command="{Binding DataContext.DeletePlantCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}" CommandParameter="{Binding}" Style="{StaticResource ActionButton}" Background="#F44336" Foreground="White"/> </StackPanel> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> <!-- 分页控制 --> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Grid.Row="2" Margin="0,10"> <Button Content="首页" Command="{Binding FirstPageCommand}" Style="{StaticResource ActionButton}"/> <Button Content="上一页" Command="{Binding PreviousPageCommand}" Style="{StaticResource ActionButton}"/> <TextBlock Text="{Binding CurrentPage, StringFormat='第 {0} 页'}" VerticalAlignment="Center" Margin="10,0"/> <Button Content="下一页" Command="{Binding NextPageCommand}" Style="{StaticResource ActionButton}"/> <Button Content="末页" Command="{Binding LastPageCommand}" Style="{StaticResource ActionButton}"/> <TextBlock Text="每页数量:" VerticalAlignment="Center" Margin="10,0,5,0"/> <ComboBox ItemsSource="{Binding PageSizeOptions}" SelectedItem="{Binding PageSize}" Width="80" Margin="0,0,10,0"/> <TextBlock Text="{Binding TotalCount, StringFormat='共 {0} 条记录'}" VerticalAlignment="Center"/> </StackPanel> <!-- 状态栏 --> <StatusBar Grid.Row="2" VerticalAlignment="Bottom"> <StatusBarItem> <TextBlock Text="{Binding StatusMessage}"/> </StatusBarItem> </StatusBar> </Grid> </Window> 前端代码如上 using Autodesk.AutoCAD.Windows.Data; using FengJing.Views.OtherView; using GalaSoft.MvvmLight.Command; using OfficeOpenXml; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Data.Entity; using System.IO; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; namespace FengJing.Services.PlantLibModule { public static class PlantImportService { public static List<Plant> ImportFromFile(string filePath) { var plants = new List<Plant>(); if (filePath.EndsWith(".xlsx") || filePath.EndsWith(".xls")) { // 使用 EPPlus 或其他库处理 Excel using (var package = new ExcelPackage(new FileInfo(filePath))) { // 检查工作簿中是否有工作表 if (package.Workbook.Worksheets.Count == 0) { throw new ApplicationException("Excel文件中不包含任何工作表"); } var worksheet = package.Workbook.Worksheets[1]; int rowCount = worksheet.Dimension.Rows; for (int row = 2; row <= rowCount; row++) // 第一行是标题 { plants.Add(new Plant { Name = worksheet.Cells[row, 1].Text, Type = new PlantType{ Name = worksheet.Cells[row, 2].Text }, SuitableRegion = new SuitableRegionrClass { CityName = worksheet.Cells[row, 3].Text }, EvergreenDeciduous = new EvergreenDeciduousClass { EvergreenName = worksheet.Cells[row, 4].Text }, OrnamentalValue = new OrnamentalValueClass { OrnamentalValueName = worksheet.Cells[row, 5].Text }, Price = decimal.Parse(worksheet.Cells[row, 6].Text), ColorPeriod = new ColorPeriodClass { ColorPeriodName = worksheet.Cells[row, 7].Text }, Color = new ColorClass { ColorName = worksheet.Cells[row, 8].Text }, Unit = new customUnitClass { UnitName = worksheet.Cells[row, 9].Text }, Diameter = double.Parse(worksheet.Cells[row, 10].Text), CrownWidth = double.Parse(worksheet.Cells[row, 11].Text), Height = double.Parse(worksheet.Cells[row, 12].Text), PlantingDensity = double.Parse(worksheet.Cells[row, 13].Text), Habit = worksheet.Cells[row, 14].Text, WetDroughtTolerance = worksheet.Cells[row, 15].Text, IsSpongePlant = worksheet.Cells[row, 16].Text, CreateAt = DateTime.Now }); } } } //else if (filePath.EndsWith(".csv")) //{ // // 使用 CsvHelper 或 StreamReader 处理 CSV // var lines = File.ReadAllLines(filePath); // for (int i = 1; i < lines.Length; i++) // 跳过标题行 // { // var values = lines[i].Split(','); // plants.Add(new Plant // { // Name = values[0], // Category = values[1], // Price = decimal.Parse(values[2]), // // 其他属性... // }); // } //} return plants; } } public class PlantListViewModel { // 搜索条件属性 public string SearchName { get; set; } public string SearchType { get; set; } public string SearchColor { get; set; } public string SearchUnit { get; set; } public string SearchSuitableRegion { get; set; } public string SearchHabit { get; set; } public string SearchWetDroughtTolerance { get; set; } public string SearchIsSpongePlant { get; set; } public string SearchEvergreenDeciduous { get; set; } public string SearchOrnamentalValue { get; set; } public string SearchColorPeriod { get; set; } public string SearchDiameter { get; set; } public string SearchHeight { get; set; } public string SearchCrownWidth { get; set; } public string SearchPrice { get; set; } private readonly plantService _plantService = new plantService(); // 分页相关属性 private int _currentPage = 1; private int _pageSize = 20; private int _totalCount; private string _searchText; public string SearchText { get => _searchText; set { _searchText = value; OnPropertyChanged(); } } public ObservableCollection<Plant> Plants { get; } = new ObservableCollection<Plant>(); public Plant SelectedPlant { get; set; } public int CurrentPage { get => _currentPage; set => SetField(ref _currentPage, value); } public int PageSize { get => _pageSize; set { if (SetField(ref _pageSize, value)) { LoadPlants(); } } } public List<int> PageSizeOptions { get; } = new List<int> { 10, 20, 50, 100 }; public int TotalCount { get => _totalCount; set => SetField(ref _totalCount, value); } public string StatusMessage { get; set; } // 命令 public ICommand AddPlantCommand { get; } public ICommand EditPlantCommand { get; } public ICommand DeletePlantCommand { get; } public ICommand RefreshCommand { get; } //public ICommand SearchCommand { get; } public ICommand FirstPageCommand { get; } public ICommand PreviousPageCommand { get; } public ICommand NextPageCommand { get; } public ICommand LastPageCommand { get; } public ICommand ImportCommand { get; } public ICommand ViewImageCommand { get; } public ICommand SearchCommand { get; } public ICommand ClearSearchCommand { get; } public PlantListViewModel() { // 初始化命令 AddPlantCommand = new RelayCommand(AddPlant); EditPlantCommand = new RelayCommand<Plant>(EditPlant); DeletePlantCommand = new RelayCommand<Plant>(DeletePlant); RefreshCommand = new RelayCommand(LoadPlants); SearchCommand = new RelayCommand(ExecuteSearch); ClearSearchCommand = new RelayCommand(ClearSearchConditions); FirstPageCommand = new RelayCommand(() => ChangePage(1)); PreviousPageCommand = new RelayCommand(() => ChangePage(CurrentPage - 1)); NextPageCommand = new RelayCommand(() => ChangePage(CurrentPage + 1)); LastPageCommand = new RelayCommand(() => ChangePage(TotalPages)); ImportCommand = new RelayCommand(ImportPlants); ViewImageCommand = new RelayCommand<Plant>(ShowPlantImage); // 加载数据 LoadPlants(); } private int TotalPages => (int)Math.Ceiling((double)TotalCount / PageSize); private void LoadPlants() { try { var result = _plantService.GetPlants(CurrentPage, PageSize, SearchText); Plants.Clear(); foreach (var plant in result.Plants) { Plants.Add(plant); } TotalCount = result.TotalCount; StatusMessage = $"成功加载 {Plants.Count} 条苗木记录"; } catch (Exception ex) { StatusMessage = $"加载失败: {ex.Message}"; } } private void SearchPlants() { CurrentPage = 1; LoadPlants(); } private void ChangePage(int page) { if (page < 1 || page > TotalPages) return; CurrentPage = page; LoadPlants(); } private void AddPlant() { var createWindow = new CreatePlant(); // 安全访问 Application.Current if (Application.Current != null) { createWindow.Owner = Application.Current.MainWindow; } else { // 处理非 WPF 环境的情况 createWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen; } createWindow.ShowDialog(); // 添加完成后刷新列表 LoadPlants(); } private void ShowPlantImage(Plant plant) { if (plant == null) return; var showImageWindow = new ImageShow(plant); Autodesk.AutoCAD.ApplicationServices.Application.ShowModalWindow(showImageWindow); } private void EditPlant(Plant plant) { if (plant == null) return; var updateWindow = new UpdatePlant(plant); Autodesk.AutoCAD.ApplicationServices.Application.ShowModalWindow(updateWindow); // 更新完成后刷新列表 LoadPlants(); } private void DeletePlant(Plant plant) { if (plant == null) return; var result = MessageBox.Show($"确定要删除苗木 '{plant.Name}' 吗?", "确认删除", MessageBoxButton.YesNo, MessageBoxImage.Warning); if (result == MessageBoxResult.Yes) { try { bool success = _plantService.DeletePlant(plant.Id); if (success) { StatusMessage = $"苗木 '{plant.Name}' 已删除"; LoadPlants(); } else { StatusMessage = "删除失败"; } } catch (Exception ex) { StatusMessage = $"删除失败: {ex.Message}"; } } } // 导入方法实现 private void ImportPlants() { try { // 创建打开文件对话框 var openFileDialog = new Microsoft.Win32.OpenFileDialog { Filter = "Excel 文件|*.xlsx;*.xls|CSV 文件|*.csv|所有文件|*.*", Title = "选择苗木列表文件" }; if (openFileDialog.ShowDialog() == true) { string filePath = openFileDialog.FileName; // 调用导入逻辑 var importedPlants = PlantImportService.ImportFromFile(filePath); // 处理导入的数据(示例) foreach (var plant in importedPlants) { // 保存到数据库 plantService pService = new plantService(); bool bSave = pService.AddPlant(plant); } // 刷新列表 LoadPlants(); MessageBox.Show($"成功导入 {importedPlants.Count} 条苗木记录"); } } catch (Exception ex) { MessageBox.Show($"导入失败: {ex.Message}"); } } // 执行搜索 private void ExecuteSearch() { var query = dbContext.Plants.AsQueryable(); // 根据条件进行精确搜索 if (!string.IsNullOrEmpty(SearchName)) query = query.Where(p => p.Name == SearchName); if (!string.IsNullOrEmpty(SearchType)) query = query.Where(p => p.Type == SearchType); if (!string.IsNullOrEmpty(SearchColor)) query = query.Where(p => p.Color == SearchColor); // 同样处理其他条件... // 处理数值型条件 if (!string.IsNullOrEmpty(SearchDiameter)) { if (double.TryParse(SearchDiameter, out var diameter)) query = query.Where(p => p.Diameter == diameter); } if (!string.IsNullOrEmpty(SearchHeight)) { if (double.TryParse(SearchHeight, out var height)) query = query.Where(p => p.Height == height); } if (!string.IsNullOrEmpty(SearchPrice)) { if (decimal.TryParse(SearchPrice, out var price)) query = query.Where(p => p.Price == price); } // 应用分页 TotalCount = query.Count(); Plants = new ObservableCollection<Plant>(query .Skip((CurrentPage - 1) * PageSize) .Take(PageSize) .ToList()); } // 清除搜索条件 private void ClearSearchConditions() { SearchName = ""; SearchType = ""; SearchColor = ""; SearchUnit = ""; SearchSuitableRegion = ""; SearchHabit = ""; SearchWetDroughtTolerance = ""; SearchIsSpongePlant = ""; SearchEvergreenDeciduous = ""; SearchOrnamentalValue = ""; SearchColorPeriod = ""; SearchDiameter = ""; SearchHeight = ""; SearchCrownWidth = ""; SearchPrice = ""; // 通知所有属性已更改 OnPropertyChanged(nameof(SearchName)); OnPropertyChanged(nameof(SearchType)); OnPropertyChanged(nameof(SearchColor)); OnPropertyChanged(nameof(SearchUnit)); OnPropertyChanged(nameof(SearchSuitableRegion)); OnPropertyChanged(nameof(SearchHabit)); OnPropertyChanged(nameof(SearchWetDroughtTolerance)); OnPropertyChanged(nameof(SearchIsSpongePlant)); OnPropertyChanged(nameof(SearchEvergreenDeciduous)); OnPropertyChanged(nameof(SearchOrnamentalValue)); OnPropertyChanged(nameof(SearchColorPeriod)); OnPropertyChanged(nameof(SearchDiameter)); OnPropertyChanged(nameof(SearchHeight)); OnPropertyChanged(nameof(SearchCrownWidth)); OnPropertyChanged(nameof(SearchPrice)); // 清除后重新加载数据 LoadPlants(); } // INotifyPropertyChanged 实现 public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null) { if (EqualityComparer<T>.Default.Equals(field, value)) return false; field = value; OnPropertyChanged(propertyName); return true; } } } 后端代码如上,怎么适配一下
最新发布
07-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值