wpf viewmodel和界面双向通知

通知模型(Model)或视图模型(ViewModel) 这两个有什么区别?分别给我代码例子


在MVVM(Model-View-ViewModel)架构中,ModelViewModel扮演不同的角色:

  • Model表示应用程序的数据域,负责业务逻辑和数据访问。它通常不直接与用户界面交互。
  • ViewModel作为ModelView之间的桥梁,包含展示逻辑和命令,以及用户交互逻辑。它通常包括对Model的引用,并实现INotifyPropertyChanged接口,以便在数据发生变化时更新视图。

以下是ModelViewModel的简单代码例子:

Model(模型)

// 一个简单的Model,不实现INotifyPropertyChanged,因为它不需要直接更新UI
public class User
{public string Name { get; set; }public int Age { get; set; }// 其他业务逻辑和数据访问方法
}

ViewModel(视图模型)

// 实现INotifyPropertyChanged接口的ViewModel
public class UserViewModel : INotifyPropertyChanged
{private User user;public string Name{get { return user.Name; }set{if (user.Name != value){user.Name = value;OnPropertyChanged();}}}public int Age{get { return user.Age; }set{if (user.Age != value){user.Age = value;OnPropertyChanged();}}}public UserViewModel(User user){this.user = user;}public event PropertyChangedEventHandler PropertyChanged;protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}
}

在这个例子中,User类是一个简单的数据模型,包含NameAge两个属性。它代表应用程序的数据层,负责定义数据属性和业务逻辑。

UserViewModel类则是视图模型,它包含了一个User实例。视图模型通过暴露NameAge属性,并在它们的setter中调用OnPropertyChanged方法,将User模型的改变通知给界面。这样,当视图(UI)中的数据变化时,这些变化会反映到模型实例中,同时如果模型属性在代码中被修改,UI也会得到更新。这就是双向数据绑定。

通常,ViewModel中还会包含命令(比如ICommand实现),用于响应用户交互,如按钮点击等。这些命令可能会改变模型的状态或触发业务逻辑。这部分逻辑被封装在视图模型中,而不是在模型本身,以保持模型的独立性和重用性。

根据上面的后端代码,xaml代码实现界面修改修改model数据


根据提供的后端代码,我们可以在XAML中设置绑定,以便用户界面可以修改Model数据。假设我们的ModelUser类,ViewModelUserViewModel类。

首先,确保MainWindowDataContext设置为我们的UserViewModel

<Window x:Class="WpfApp.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:WpfApp"Title="MainWindow" Height="350" Width="525"><Window.DataContext><!-- 这里假设你已经在XAML的Code-behind中创建了UserViewModel的实例并赋值给this.DataContext --></Window.DataContext><!-- ... -->
</Window>

接下来,在XAML中,我们添加两个TextBox控件,分别绑定到ViewModelNameAge属性:

<Grid><StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center"><Label Content="Name:"/><TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" /><Label Content="Age:"/><TextBox Text="{Binding Age, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" /></StackPanel>
</Grid>

在上面的代码中:

  • Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" 表示TextBox的文本将与UserViewModel中的Name属性进行双向绑定。UpdateSourceTrigger=PropertyChanged表示每当文本框的内容发生变化时,ViewModel中的Name属性也会随之更新。
  • 同样的,Text="{Binding Age, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"将年龄输入框与ViewModel中的Age属性进行双向绑定。

在这种设置下,用户界面上对TextBox的任何更改都会即时更新到UserViewModel中,进而通过它的setter方法更新到User模型中。同样地,如果User模型中的数据在后端代码中被改变,它也会通过INotifyPropertyChanged接口通知界面,使得界面上的显示也会更新。

注意:实际应用中,你需要在你的窗口的代码后面(code-behind)创建UserViewModel的实例,并将它设为窗口的DataContext。例如:

public MainWindow()
{InitializeComponent();User user = new User() { Name = "Alice", Age = 30 };this.DataContext = new UserViewModel(user);
}

确保你的UserUserViewModel类在同一个命名空间中,或者你已经在XAML文件的顶部通过xmlns:local指令引入了正确的命名空间。

有一个问题,Mode=TwoWay设置双向,viewmodel里的nodification是不是就工程重复?


实际上,Mode=TwoWay的设置和ViewModel中的通知(notification)是双向绑定机制中两个互补的部分:

  1. 从界面到模型(View -> ViewModel/Model):

    • Mode=TwoWay的绑定确保了界面元素(例如TextBox)的更改会被推送到数据模型中去。在ViewModel的属性设置器(setter)中,这些更改会被接收并用来更新模型。
  2. 从模型到界面(ViewModel/Model -> View):

    • 当数据模型的状态在代码中被改变时(可能是来自另一个绑定的界面元素的更改,或是后台逻辑的结果),INotifyPropertyChanged接口的实现允许ViewModel通知界面更新。PropertyChanged事件的触发会导致绑定到这个特定属性的界面元素更新其显示。

这并不是冗余的,而是确保了无论数据变化是由用户界面引起的还是由代码逻辑引起的,所有的变化都会同步。也就是说:

  • 当用户在TextBox中输入文字时,TextBoxText属性会发生变化,这个变化通过绑定推送到ViewModel的对应属性。如果ViewModel的属性设置器中有附加的逻辑,它会执行,并且通过INotifyPropertyChanged通知界面更新。
  • 如果有一些非界面逻辑改变了ViewModel的属性(比如,来自网络的数据更新),ViewModel将通过PropertyChanged事件通知界面元素更新其显示,即使这个更改是在界面之外发生的。

Mode=TwoWay确保了这个通信是双向的,而INotifyPropertyChanged接口则确保了界面始终能够显示最新的数据状态。这就是为什么在MVVM模式中ViewModel通常会实现这个接口。

Mode=TwoWay确保了这个通信是双向的 和Mode=OneWay什么区别


在WPF的数据绑定机制中,Mode=TwoWayMode=OneWay的主要区别在于数据更新的方向:

  • Mode=TwoWay:数据绑定是双向的。这意味着任何一端的更改(无论是源对象还是目标对象)都会更新另一端。例如,如果你将一个TextBoxText属性绑定到一个模型的Name属性,并设置为TwoWay模式,那么当TextBox中的文本更改时,Name属性会更新,反之亦然。

  • Mode=OneWay:数据绑定只是单向的,只从源对象更新到目标对象。源对象的更改会影响目标对象,但目标对象的更改不会影响源对象。如果你将一个TextBlockText属性绑定到模型的Name属性,并设置为OneWay模式,那么只有当Name属性更改时,TextBlock的显示文本才会更新。如果TextBlock的内容发生变化(虽然TextBlock通常不用于输入),它不会影响Name属性。

通常,对于用户输入控件(如TextBox),如果你希望模型在用户输入时被更新,你会使用Mode=TwoWay。而对于只用于显示数据的控件(如TextBlock),你会使用Mode=OneWay,因为用户不会更改显示数据,你只需要从模型获取数据来显示。

下面是一个简单的示例来说明这两种绑定模式:

<!-- TwoWay绑定 -->
<TextBox Text="{Binding Name, Mode=TwoWay}"/><!-- OneWay绑定 -->
<TextBlock Text="{Binding Name, Mode=OneWay}"/>

默认情况下,WPF中某些属性的绑定模式如下:

  • TextBox.Text默认是TwoWay绑定。
  • TextBlock.Text默认是OneWay绑定。

在设计用户界面和交互时,选择合适的绑定模式是非常重要的,以确保程序逻辑的正确性和高效性。

哦,OneWay是在实现INotifyPropertyChanged的功能上,才能有viewmodel属性修改,界面才会改变。TwoWay才是有界面修改更改viewmodel的属性?


是的,您的理解是正确的。在WPF数据绑定中,OneWayTwoWay绑定模式与INotifyPropertyChanged接口的使用密切相关,它们定义了数据更改时更新的方向:

  • OneWay绑定:数据从源(如ViewModel的属性)流向目标(如View中的UI元素)。这种模式下,只有当源对象的属性发生变化时,目标UI元素才会更新。要使OneWay绑定工作,源对象的属性更改必须触发PropertyChanged事件。这通常用于只显示数据的UI元素,例如标签(Label)或文本块(TextBlock)。

  • TwoWay绑定:数据在源和目标之间双向流动。这意味着当UI元素(目标)上的数据更改时(例如用户编辑了TextBox中的文本),这个更改会被推回到源对象(ViewModel的属性),并且如果源对象的属性更改,UI元素也会更新。TwoWay绑定通常用于用户可以交互和修改数据的UI元素,例如文本框(TextBox)。

这里有一个示例:

<!-- 使用OneWay绑定 -->
<TextBlock Text="{Binding UserName, Mode=OneWay}"/><!-- 使用TwoWay绑定 -->
<TextBox Text="{Binding UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

在上述示例中:

  • TextBlock 使用OneWay绑定:这意味着如果ViewModel中的UserName属性更改,TextBlock将显示新的用户名,但如果TextBlockText在某处被代码更改,这不会影响ViewModel中的UserName属性。
  • TextBox 使用TwoWay绑定:这意味着不仅当ViewModel中的UserName属性更改时TextBox会更新显示,而且当用户在TextBox中输入新的用户名时,ViewModel中的UserName属性也会更新。这是通过属性的setter和PropertyChanged事件相结合实现的。

在使用TwoWay绑定模式时,通常也会设置UpdateSourceTrigger属性。这个属性定义了更改推回源的时机。对于TextBox控件,默认的UpdateSourceTriggerLostFocus,这意味着当TextBox失去焦点时源属性才会更新。设置为PropertyChanged意味着每当TextBox中的文本更改时,无论焦点如何,源属性都会立即更新。

twoway会不会修改无限循环通知修改?


在正常情况下,使用TwoWay绑定不会导致无限循环。WPF的数据绑定机制被设计为能够处理属性变更通知而不引入循环。当你通过UI更改一个属性,它会更新绑定的ViewModel中的属性,该属性的setter会调用OnPropertyChanged方法通知UI属性已更改。由于绑定的更新通常是条件性的,只有在新值和旧值不相等时才进行更新,这阻止了潜在的无限循环。

例如,看下面的属性setter

private string name;
public string Name
{get { return name; }set{if (name != value){name = value;OnPropertyChanged(nameof(Name));}}
}

在这里,OnPropertyChanged只有在name的当前值与新值不相同的情况下才会被调用。这就防止了无限循环,因为当新值和当前值相等时,不会发出属性更改通知,UI也就不会尝试再次更新这个值。

然而,如果setter实现有误,例如忽略了值是否真的发生变化,或者在某些情况下错误地更改了另一个属性,它仍然可能导致无限循环:

public string Name
{get { return name; }set{name = value; // 这里没有检查值是否相等OnPropertyChanged(nameof(Name)); // 这将无条件地触发PropertyChanged事件}
}

上面的代码无论name值是否发生了变化,都会触发PropertyChanged事件。如果UI自动响应这个事件去更新name,那么就会形成一个循环。

确保你的属性setter总是检查值是否真的变化了,并且只有在值变化时才触发PropertyChanged事件,这样可以防止无限循环。

哦,也就是属性修改一次,通知界面界面修改,如果界面是源值修改通知,那么会通知绑定viewmodel属性,这时属性手动通知,再发给界面,界面的值没有修改,就不会发通知给viewmodel了吧?


是的,您描述的过程基本上正确了解了TwoWay绑定和INotifyPropertyChanged机制如何合作以避免无限循环。

具体来说,流程如下:

  1. 用户界面更改:当用户在界面上更改了一个绑定到ViewModel属性的控件(如TextBox)的值时,这个新值会被推送到ViewModel的相应属性。

  2. 属性更新:在ViewModel中,对应的属性的setter被调用。在这个setter中,通常会有一个检查来判断新值是否真的和旧值不同。

  3. 通知变化:如果值确实改变了,属性的setter会更新内部变量,并触发PropertyChanged事件,通知界面属性已更改。

  4. 界面响应变化:界面接收到PropertyChanged事件后,会更新显示该属性的界面元素。如果界面元素的显示已经与新的属性值相符,则不会重新触发数据更新回ViewModel

这个过程保证了数据在ViewModel和界面之间同步,而不会引起无限循环。PropertyChanged事件确保只有在数据实际改变时才通知界面更新,而界面上的控件(如果已正确实现)在接收到与其当前值相同的数据时不应再触发更改。这样的设计是数据绑定框架的一部分,目的就是为了有效地管理数据流和更新,避免因为反复无意义的数据推送和更新而导致性能问题或逻辑错误。

如果界面元素的显示已经与新的属性值相符,则不会重新触发数据更新回ViewModel。 这段有代码的具体实现细节吗?


在WPF中,数据绑定框架内部处理确保不会因为值未变而触发无谓的更新,是通过数据绑定机制的一部分实现的。这里面涉及的具体细节通常是透明的,即不需要开发者额外编码来控制。但理解其背后的基本概念是有帮助的。

WPF 数据绑定和更新机制

在WPF中,数据绑定系统使用Binding对象来连接数据源的属性与界面元素。当绑定设置为TwoWay时,以下是更新过程的简化版:

  1. 源值更新: 当用户界面(如TextBox)的值改变,且绑定的UpdateSourceTrigger设置为默认(对于TextBox来说通常是LostFocus)或PropertyChanged时,绑定机制会读取控件的新值,并尝试将其写回到绑定的数据源属性。

  2. 调用属性的Setter: 数据源(通常是ViewModel的某个属性)的setter被调用,如果新值与当前值相同,则可以在setter内部直接返回,不做任何处理:

    private string _name;
    public string Name
    {get { return _name; }set{if (_name == value) return;  // 如果新值和旧值相同,则不进行后续操作_name = value;OnPropertyChanged(nameof(Name));}
    }
    

    这种检查确保只有在实际需要更新时才会触发PropertyChanged事件。

  3. 触发PropertyChanged: 如果值确实发生了变化,则触发PropertyChanged事件,这会通知界面组件更新显示的值。

  4. 界面响应: 界面元素收到PropertyChanged事件后,会检查事件中指示的属性是否与自己绑定的属性相同,如果不相同,则更新其显示的值。如果界面元素的新值与界面当前显示的值相同,这通常由界面框架负责检查,然后不会进行无谓的DOM更新或重绘。

这一流程是高度优化的。WPF和其他现代UI框架(如Xamarin、UWP)设计有很多内部机制来最小化不必要的更新,以提高性能和响应速度。

代码示例

虽然大部分细节是自动处理的,您可以通过如下方式编写代码来避免无谓的更新:

public class MyViewModel : INotifyPropertyChanged
{private int _myProperty;public int MyProperty{get { return _myProperty; }set{if (value != _myProperty){_myProperty = value;OnPropertyChanged(nameof(MyProperty));}}}public event PropertyChangedEventHandler PropertyChanged;protected virtual void OnPropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}
}

在这个例子中,PropertyChanged只有在_myProperty的值真正改变时才会触发。这是防止无限循环的一种常见和有效的模式。

总之,通过合理使用属性检查和慎重触发PropertyChanged事件,可以有效避免无限循环及无谓的性能消耗。

UpdateSourceTrigger几种方式


在WPF中,UpdateSourceTrigger属性定义了绑定源(通常是ViewModel中的属性)何时接收来自绑定目标(界面元素,如TextBox)的更新。这个属性主要用在TwoWayOneWayToSource绑定模式下,指定用户界面元素值的变化何时传递回绑定的数据源。以下是UpdateSourceTrigger的几种常见设置方式:

1. Default

Default是大多数绑定属性的默认触发器,具体行为取决于绑定的属性。例如,TextBox.Text属性的默认触发器是LostFocus,而大多数其他属性的默认触发器是PropertyChanged。这意味着,如果你没有显式设置UpdateSourceTrigger,它将采用默认行为:

<TextBox Text="{Binding Path=UserName, Mode=TwoWay}"/>
<!-- 默认是 LostFocus -->

2. PropertyChanged

当设置为PropertyChanged时,每当绑定的界面元素(如TextBoxText属性)变化时,即时更新数据源,不需要等到控件失去焦点:

<TextBox Text="{Binding Path=UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

这种方式在需要实时搜索或实时数据处理的场景中非常有用。

3. LostFocus

当设置为LostFocus时,只有当绑定的界面元素失去焦点时,才会更新数据源。这是TextBox.Text属性的默认行为,有助于避免在用户仍在输入时频繁更新数据源:

<TextBox Text="{Binding Path=UserName, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/>
<!-- 通常不需要显式设置,因为这是默认行为 -->

4. Explicit

Explicit触发器需要开发者手动调用BindingExpression.UpdateSource方法来更新数据源。这种方式允许开发者完全控制何时更新数据源,通常用在用户完成一系列输入步骤后,点击“保存”按钮时:

<TextBox Name="MyTextBox" Text="{Binding Path=UserName, Mode=TwoWay, UpdateSourceTrigger=Explicit}"/>
<Button Content="Update" Click="Update_Click"/>
private void Update_Click(object sender, RoutedEventArgs e)
{BindingExpression be = MyTextBox.GetBindingExpression(TextBox.TextProperty);be.UpdateSource();
}

这种方式在需要用户确认输入或需要批量更新数据的场景中非常有用,因为它可以防止不必要的数据更新和潜在的性能问题。

总结来说,UpdateSourceTrigger的选择依赖于具体的应用场景和需求,它为开发者提供了灵活的数据更新策略,使得可以根据用户交互的特点和性能考虑来优化数据流。

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

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

相关文章

Redis中的集群(五)

集群 在集群中执行命令 MOVED错误。 当节点发现键所在的槽并非由自己负责处理的时候&#xff0c;节点就会向客户端返回一个MOVED错误&#xff0c;指引客户端转向至正在负责槽的节点&#xff0c;MOVED错误的格式为: MOVED <slot> <ip>:<port>其中slot为键…

centos 7.9 nginx本地化安装,把镜像改成阿里云

1.把centos7.9系统切换到阿里云的镜像源 1.1.先备份 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup1.2.下载新的CentOS-Base.repo配置文件 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo特别…

盲人独立出行的新里程:“盲人软件”赋能无障碍生活

作为一名资深记者&#xff0c;我始终致力于探索并分享那些以科技之力提升特殊群体生活质量的故事。最近&#xff0c;一款名为蝙蝠避障的盲人软件进入了我的视野&#xff0c;其强大的避障导航功能正悄然改变着视障人士的出行方式&#xff0c;赋予他们前所未有的独立生活能力。 …

【多线程】线程池Future和FutureTask

【多线程】线程池Future和FutureTask 【一】Future概述【1】Future的出现原因【2】Future结构图 【二】Future详解【1】Future接口源码【2】Future的5个方法【3】ThreadPoolExecutor提供了三个方法&#xff0c;来获取返回值&#xff08;1&#xff09;submit(Runnable r)&#x…

利用数组储存表格数据

原理以及普通数组储存表格信息 在介绍数组的时候说过&#xff0c;数组能够用来储存任何同类型的数据&#xff0c;这里的意思就表明只要是同一个类型的数组据就可以储存到一个数组中。那么在表格中同一行的数据是否可以储存到同一个数组中呢&#xff1f;答案自然是可以&#xff…

【ARM 裸机】汇编 led 驱动之原理分析

1、我们为什么要学习汇编&#xff1f;&#xff1f;&#xff1f; 之前我们或许接触过 STM32 以及其他的 32 位的 MCU ,都是基于 C 语言环境进行编程的&#xff0c;都没怎么注意汇编&#xff0c;是因为 ST 公司早已将启动文件写好了&#xff0c;新建一个 STM32 工程的时候&#…

回归预测 | Matlab实现SSA-GRNN麻雀算法优化广义回归神经网络多变量回归预测(含优化前后预测可视化)

回归预测 | Matlab实现SSA-GRNN麻雀算法优化广义回归神经网络多变量回归预测(含优化前后预测可视化) 目录 回归预测 | Matlab实现SSA-GRNN麻雀算法优化广义回归神经网络多变量回归预测(含优化前后预测可视化)预测效果基本介绍程序设计参考资料预测效果

图像生成:Pytorch实现一个简单的对抗生成网络模型

图像生成&#xff1a;Pytorch实现一个简单的对抗生成网络模型 前言相关介绍具体步骤准备并读取数据集定义生成器定义判别器定义损失函数定义优化器开始训练完整代码 训练生成的图片 前言 由于本人水平有限&#xff0c;难免出现错漏&#xff0c;敬请批评改正。更多精彩内容&…

Linux losetup命令教程:设置和控制循环设备(附实例详解和注意事项)

Linux losetup命令介绍 losetup&#xff08;Loop device setup&#xff09;命令在Linux操作系统中用于设置和控制循环设备。循环设备是一种伪设备&#xff0c;它使文件可以作为块设备进行访问。如果只给出了loopdev参数&#xff0c;那么将显示相应循环设备的状态。 Linux los…

实战Java高并发程序设计课

课程介绍 实战Java高并发程序设计课是一门针对Java开发者的培训课程&#xff0c;重点关注如何设计和优化高并发的程序。学员将学习到并发编程的基本概念、线程池的使用、锁机制、并发集合等技术&#xff0c;并通过实际案例进行实践操作。这门课程旨在帮助开发者掌握并发编程的…

【2024年5月备考新增】《软考案例分析答题技巧(5)采购、配置与变更、其他》

2.10 项目采购管理 采购管理过程:规划采购管理-实施采购-控制采购。 釆购步骤: ①准备釆购工作说明书(SOW)或工作大纲(TOR); ②准备高层级的成本估算,制定预算; ③发布招标广告; ④确定合格卖方的名单; ⑤准备并发布招标文件; ⑥由卖方准备并提交建议书; ⑦对建…

最祥解决python 将Dataframe格式数据上传数据库所碰到的问题

碰到的问题 上传Datafrane格式的数据到数据库 会碰见很多错误 举几个很普遍遇到的问题(主要以SqlServer举例) 这里解释下 将截断字符串或二进制数据 这个是字符长度超过数据库设置的长度 然后还有字符转int失败 或者字符串转换日期/或时间失败 这个是碰到的需要解决的最多的问…

Java面试题戏剧

目录 第一幕 、第一场&#xff09;某大厦楼下大门前第二场&#xff09;电梯中第三场&#xff09;走廊中 第二幕、第一场&#xff09;公司前台第二场&#xff09;公司卫生间 第三幕、第一场&#xff09;一场异常面试 第四幕 、第一场&#xff09;大厦楼下门口第二场&#xff09;…

Lobe UI - 基于 AntDesign 开发的 AIGC Web 应用的开源 UI 组件库

今天推荐一个可以快速开发 ChatGPT UI 界面的组件库&#xff0c;质量很高&#xff0c;拿来就能用。 Lobe UI 是由 lobehub 团队开发的一套 web UI 组件库&#xff0c;和我之前推荐的很多通用型的 UI 组件库不同&#xff0c;Lobe UI 是专门为目前火热的 AIGC 应用开发而打造&am…

Objective-C学习笔记(内存管理、property参数)4.9

1.引用计数器retainCount&#xff1a;每个对象都有这个属性&#xff0c;默认值为1&#xff0c;记录当前对象有多少人用。 为对象发送一条retain/release消息&#xff0c;对象的引用计数器加/减1&#xff0c;为对象发一条retainCount,得到对象的引用计数器值&#xff0c;当计数器…

上海计算机学会 2023年6月月赛 乙组T3 工作安排(结构体排序、贪心算法)

第三题&#xff1a;T3工作安排 标签&#xff1a;结构体排序、贪心算法 题意&#xff1a;有 n n n份任务。完成第 i i i份任务需要 t i t_i ti​的时间&#xff0c;在这份任务没有完成之前&#xff0c;每一个单位时间会收到 f i f_i fi​单位的罚款。求以什么顺序安排这些任务&…

鸿蒙实战开发-如何实现选择并查看文档与媒体文件

介绍 应用使用ohos.file.picker、ohos.multimedia.mediaLibrary、ohos.file.fs 等接口&#xff0c;实现了picker拉起文档编辑保存、拉起系统相册图片查看、拉起视频并播放的功能。 效果预览 使用说明&#xff1a; 在首页&#xff0c;应用展示出最近打开过的文档信息&#xf…

【AcWing】蓝桥杯集训每日一题Day22|区间DP|博弈论|1388.游戏(C++)

1388.游戏 1388. 游戏 - AcWing题库难度&#xff1a;中等时/空限制&#xff1a;1s / 64MB总通过数&#xff1a;1429总尝试数&#xff1a;1925来源&#xff1a;usaco training 3.3算法标签博弈论DP区间DP 题目内容 玩家一和玩家二共同玩一个小游戏。 给定一个包含 N 个正整数的…

【MATLAB 分类算法教程】_3麻雀搜索算法优化支持向量机SVM分类 - 教程和对应MATLAB代码

分类代码案例3:麻雀搜索算法优化支持向量机SVM分类 - MATLAB完全代码教程 1. 初始化代码2.读取数据代码3.数据预处理代码4.利用麻雀搜索算法SSA求解最佳的SVM参数c和g代码5.根据最佳的参数进行SVM模型训练代码6.SVM模型预测代码7.准确率分析以及分类结果对比作图代码本文以红酒…

Python中的生成器与迭代器:概念、区别及其实用性解析

Python中的生成器与迭代器&#xff1a;概念、区别及其实用性解析 在Python编程中&#xff0c;生成器&#xff08;Generators&#xff09;和迭代器&#xff08;Iterators&#xff09;是处理序列数据的两个重要概念。它们为处理大量数据或复杂数据结构提供了高效且灵活的方式。本…