欢迎光临
我们一直在努力

c开发软件下载(使用C#开发ChatGPT聊天程序)

总体效果如下:

源码下载

关键点1:无边框窗口拖动

window中设置allowstransparency=”true”、 background=”transparent”以及windowstyle=”none”这样设置的话默认窗口的标题栏为不可见状态,且无法用鼠标拖动,使用windowchorme来解决

<windowchrome.windowchrome> <windowchrome captionheight=“50” useaerocaptionbuttons=“false” /> </windowchrome.windowchrome>

该设置的详细讲解参见wpf之window无边框拖动、特殊形状、grid拖拽

关键点2:输入栏实现删除按钮

定义textbox的controltemplate模板(节取重要部分)

<style x:key=“textboxpromote” targettype=“{x:type textbox}”> <setter property=“template”> <setter.value> <controltemplate targettype=“{x:type textbox}”> <border x:name=“border” cornerradius=“6” <dockpanel lastchildfill=“true”> <!–新增btn按钮,并绑定click事件–> <button x:name=“btn” grid.column=“1” background=“white” borderthickness=“0” click=“button_click” content=“&#xe8d5;” dockpanel.dock=“right” fontfamily=“./img/#iconfont” />

<scrollviewer x:name=“part_contenthost” dockpanel.dock=“left” focusable=“false” horizontalscrollbarvisibility=“hidden” verticalscrollbarvisibility=“hidden” /> </dockpanel> </border> <controltemplate.triggers> <!–新增datatrigger,当text属性部位为空时,不显示按钮,hiddern表示不显示,但是用空格来代替按钮来保持布局,而collapsed则是不显示且不保留空格–> <datatrigger binding=“{binding relativesource={relativesource self}, path=text}” value=“”> <setter targetname=“btn” property=“visibility” value=“collapsed” /> </datatrigger> </controltemplate.triggers> </controltemplate> </setter.value> </setter> </style>

实现button按钮事件

private void button_click(object sender, routedeventargs e) { button? btn = sender as button; if (btn != null) { var parent = visualtreehelper.getparent(btn); while (!(parent is textbox)) { parent = visualtreehelper.getparent(parent); } textbox txt = parent as textbox; if (txt != null) { txt.clear(); } } }

关键点3:listbox实现聊天效果

本文使用listbox来完成消息框的展示,因为涉及到发送和收到两种类型的消息,应该对应两种不同格式,所以会用到样式选择器,不知道怎么用的小伙伴可以看一下这篇文章wpf控件模板、数据模板、容器样式选择器

public class datetemplateselector:datatemplateselector { public datatemplate sendtemplate { get; set; } public datatemplate restemplate { get; set; } public override datatemplate selecttemplate(object item, dependencyobject container) { message message = (message)item;

if (message.issend) { return sendtemplate; } else { return restemplate; } } }

在windwo.resources中定义数据模板

发送模板

<datatemplate x:key=“chatsend”> <stackpanel x:name=“sendmsg” margin=“0,12,20,0” horizontalalignment=“right” orientation=“horizontal”> <stackpanel margin=“0,0,10,0” orientation=“vertical”>

<border minwidth=“50” minheight=“30” maxwidth=“{binding path=actualwidth,elementname=borderwidth}” background=“#c8dd1f” borderbrush=“#ddd” borderthickness=“1” cornerradius=“8,0,8,8”> <textbox minwidth=“30” margin=“8” verticalalignment=“center” background=“transparent” borderthickness=“0” fontsize=“14” isreadonly=“true” text=“{binding msg}” textwrapping=“wrapwithoverflow” /> </border> </stackpanel>

<border width=“35” height=“35” margin=“0,2,0,0” verticalalignment=“top” borderthickness=“0”> <border.background> <imagebrush imagesource=“/img/user.jpg” /> </border.background> </border> </stackpanel> </datatemplate>

接收模板

<datatemplate x:key=“chatres”> <stackpanel x:name=“sendmsg” margin=“0,12,20,0” horizontalalignment=“right” orientation=“horizontal”>

<border width=“35” height=“35” margin=“0,2,0,0” verticalalignment=“top” borderthickness=“0”> <border.background> <imagebrush imagesource=“/img/图标chatgpt.ico” /> </border.background> </border> <stackpanel margin=“0,0,10,0” orientation=“vertical”>

<border minwidth=“50” minheight=“30” maxwidth=“{binding path=actualwidth,elementname=borderwidth}” background=“#c8dd1f” borderbrush=“#ddd” borderthickness=“1” cornerradius=“0,8,8,8”> <textbox minwidth=“30” margin=“8” verticalalignment=“center” background=“transparent” borderthickness=“0” fontsize=“14” isreadonly=“true” maxlength=“25” text=“{binding msg}” textwrapping=“wrapwithoverflow” /> </border> </stackpanel> </stackpanel> </datatemplate>

因为发送消息和接受消息的对齐方式不同,一个是左一个是右,所以要定义下listbox.itemcontainerstyle

<style x:key=“listviewitemstyle” targettype=“{x:type listboxitem}”> <setter property=“focusvisualstyle” value=“{x:null}” /> <setter property=“template”> <setter.value> <controltemplate targettype=“{x:type listboxitem}”> <border name=“bd” margin=“1” padding=“{templatebinding padding}” background=“{templatebinding background}” borderbrush=“{templatebinding borderbrush}” borderthickness=“{templatebinding borderthickness}” snapstodevicepixels=“true”> <contentpresenter margin=“1” horizontalalignment=“{templatebinding horizontalcontentalignment}” verticalalignment=“{templatebinding verticalcontentalignment}” snapstodevicepixels=“{templatebinding snapstodevicepixels}” /> </border> </controltemplate> </setter.value> </setter> <!–判断是否为发送,从而使用不同的对齐方式–> <style.triggers> <datatrigger binding=“{binding issend}” value=“true”> <setter property=“horizontalcontentalignment” value=“stretch” /> </datatrigger> <datatrigger binding=“{binding issend}” value=“false”> <setter property=“horizontalcontentalignment” value=“left” /> </datatrigger> </style.triggers> </style>

为了实现listbox始终保持下拉到最后的状态,自定义类,重写onitemschanged方法

class scrollinglistbox : listbox { protected override void onitemschanged(system.collections.specialized.notifycollectionchangedeventargs e) { if (e.newitems == null) return; var newitemcount = e.newitems.count;

if (newitemcount > 0) this.scrollintoview(e.newitems[newitemcount 1]);

base.onitemschanged(e); } }

xaml中设置

<local:scrollinglistbox grid.row=“0” borderbrush=“#d3d3d3” borderthickness=“0,1,0,1” itemssource=“{binding path=messages, elementname=mainwindow}” scrollviewer.horizontalscrollbarvisibility=“disabled” scrollviewer.cancontentscroll=“false” selectionmode=“extended”> <listbox.itemtemplateselector> <local:datetemplateselector restemplate=“{staticresource chatres}” sendtemplate=“{staticresource chatsend}” /> </listbox.itemtemplateselector> <listbox.itemcontainerstyle> <style basedon=“{staticresource listviewitemstyle}” targettype=“{x:type listboxitem}” /> </listbox.itemcontainerstyle> </local:scrollinglistbox>

如何调用openai的接口,及各种常用参数的设置参见c#/.net开发chatgpt、openai 源码下载

本文使用 文章同步助手 同步

赞(0)
未经允许不得转载:梦马网络 » c开发软件下载(使用C#开发ChatGPT聊天程序)
分享到

评论 抢沙发

登录

找回密码

注册