我正在研究Oracle内部结构,我想知道文档中所说的“B树索引”实际上是经典的B树还是B+树? 我认为是一棵B+树,因为所有数据节点...
请考虑以下代码作为问题的示例。 班级状态: START: State = StartState() # 问题在这里 - StartState END: State = EndState() # 问题在这里 - EndStat...
React-Redux useSelector typescript type for state
我正在使用 React-Redux 中的 useSelector(state => state.SLICE_NAME) 挂钩,但是我在定义状态参数时遇到了困难。它默认设置为未知,因此当我尝试时会收到错误...
next.js 14 错误:无法读取未定义的属性(读取“get”)”
官方示例https://github.com/vercel/next.js/tree/canary/examples/next-forms在createTodo时出现错误“Error: Cannot readproperties of undefined (reading 'get')”。但是……
我已经关注了https://github.com/wax911/Vision-Barcode-Scanner/tree/master/barcode-reader/app/src/main/java/com/google/android/gms/samples这个git将 Vision api 实现到我的应用程序中。我...
Haskell do 表示法在 Scala 中没有等效的 for 理解?
考虑以下构建平衡二叉树的 Haskell 代码: 数据树 a = 节点 a (树 a) (树 a) |空的 构建 :: Int -> [(Tree Char, Int)] 构建 n = 执行 让 k = (n - 1) `div` 2...
考虑以下示例: 结构ContentView:视图{ @State var showSplash: Bool = true @Namespace var 动画命名空间 var body: 一些视图 { ZStack { 如果
Spring MVC - 为什么我在 GET 请求中需要模型对象?
看一下 Spring 提供的用于处理表单提交的示例: https://github.com/spring-guides/gs-handling-form-submission/tree/main/complete 这是 Spring MVC 控件的基本示例...
findAncestorsTree 在 TypeORM 3 中不返回父级
我正在使用TypeORM物化树。有一个称为组织的实体,每个组织都有一个父级,并且可以有多个子级。 @Entity('组织') @Tree('物化路径') 出口
Powershell 如何在 Try Catch 块中处理 Az Cli
我有以下代码...... 当找不到资源时,会引发错误,但代码继续运行...不知道为什么? 尝试{ $state=$(az synapse sql 池显示 --n...
我是一名 Verilog 初学者,我正在尝试了解在常见 FPGA 平台上实现 FSM 的最佳方法。 我看过很多鼓励 state/next_state 的论文(例如这篇)......
我研究了一些地方。他们说:更高的基数可以减少搜索深度。为什么? 我很好奇如果 B 树有许多相同的值会是什么样子? 我期待有关 b 树如何创建的详细信息...
无法将用于生产的 AppDbContext 设置替换为用于集成测试的内存数据库
我在我的 github 存储库中制作了一个最小化代码来说明问题:https://github.com/suugbut/MiniTest/tree/main。 我正在学习集成测试来测试我的最小 api。我无法取代
Rive 动画加载时间过长,出现 RangeError(索引):无效值:有效值范围为空:0
创建一个空项目并使用以下命令加载以下文件 all_animations.riv 代码 : 类 _MyHomePageState 扩展 State { 画板? _riveArtBoard; 状态机控制器?
State<WelcomePage>createState() => _WelcomePageState(); }
我对编码/flutter/dart很陌生,我试图在前进的过程中拾取东西。我正在尝试为应用程序构建欢迎页面。一切都很顺利,直到我尝试向显示密码字段添加功能......
我想要一个带有默认值的表单,并且用户输入的任何值都会被捕获。这是我的代码: 从“preact/hooks”导入{useState}; 导出默认函数 test() { 合作...
当我尝试向 Postgres 中的现有表添加约束时,为什么会收到 SQL state:23503?
我有一个特殊的 User 表 Advisor,仅包含 id 和 user_id (目前!),我尝试使用以下脚本将 user_id 设为外键: 更改表顾问 添加约束
我有一个可编辑的列表,其中可以重新订购哪些商品。我想更改重新排序颜色。怎么做? 结构虚拟列表:查看{ @State private var items = ["项目 1", "项目 2&
使用 jquery javascript 搜索 jstree 节点
我正在使用 jstree 插件来构建我的树。我的网页中有一个搜索框,我需要用户能够在其中搜索 jstree 节点。 我正在使用 jstree 插件来构建我的树。我的网页中有一个搜索框,我需要用户能够在其中搜索 jstree 节点。 <fieldset id="search"> <input type="text" name="search_field" id="search_field" value="" /> <button id="search_tree">Search</button> </fieldset> 单击搜索时,jstree 节点应展开,如果找到,节点应突出显示。如果未找到,则应向用户显示错误,如“未找到”。我的代码用于展开下面的所有节点。有没有简单的方法来搜索jstree中的所有节点? <script type="text/javascript"> $(document).ready(function(){ $("#search_tree").click(function () { var value=document.getElementById("search_field").value; $("#tree").jstree("search",value); }); $("#tree").jstree({ "xml_data" : { "ajax" : { "url" : "jstree.xml" }, "xsl" : "nest" }, "themes" : { "theme" : "classic", "dots" : true, "icons" : true }, "search" : { "case_insensitive" : true, "ajax" : { "url" : "jstree.xml" } }, "plugins" : ["themes", "xml_data", "ui","types", "search"] }); }); </script> 我收到此错误: Instances[...] 为 null 或不是对象。这是一个 jstree 错误。有什么想法吗? 我已将这段代码添加到我的函数中: "search" : { "case_insensitive" : true, "ajax" : { "url" : "jstree.xml" } }, "plugins" : ["themes", "xml_data", "ui","types", "search"] 和 创建了此功能并与我的单击按钮相关联: function myFunction() { $(document).ready(function(){ var value=document.getElementById("search_field").value; $("#search_tree").click(function () { $("#tree").jstree("search",value) }); }); } 2023年,API逐年变化。使用版本v3.3.x, 这是我的工作代码: 创建jstree实例,配置如下: 当您搜索关键字时,请使用:
ASP.NET MVC 项目模板在移动设备上无法调整为 100%
我不明白为什么 Web .Net MVC 项目上的默认模板没有在移动设备中调整为 100% 宽度。 我在视图上使用数据表: @模型IEnumerable 我不明白为什么 Web .Net MVC 项目上的默认模板没有在移动设备中调整为 100% 宽度。 我在视图上使用数据表: @model IEnumerable<iziConference.Models.EventAttendee> <h2>Participantes.</h2> <br /> <button><a style="text-decoration: none" href='@Url.Action("Create", new { eventId = ViewBag.EventId })'>Criar Participante</a></button> <button id="at-btn-refresh"> Actualizar</button> <input id="eventId" type="hidden" value="@ViewBag.EventId"> <table id="at-attendees-list" cellpadding="10" border="1" class="row-border stripe"> <thead> <tr> <th>ID</th> <th>Tipo</th> <th>Nome</th> <th>Email</th> <th>Estado </th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr id="[email protected]_Id"> <td style="padding: 5px"> @Html.DisplayFor(modelItem => item.Attendee.Id) </td> <td> @Html.DisplayFor(modelItem => item.AttendeeType) </td> <td> @Html.DisplayFor(modelItem => item.Attendee.Name) </td> <td> @Html.DisplayFor(modelItem => item.Attendee.Email) </td> <td> @if (item.IsActive) { <button id="[email protected]_Id" class="at-btn-active-state active" data-attendee-id="@item.Attendee_Id" data-attendee-name="@item.Attendee.Name" data-active-new-state="false" data-show-confirmation-alert="true">Desactivar</button> } else { <button id="[email protected]_Id" class="at-btn-active-state inactive" data-attendee-id="@item.Attendee_Id" data-attendee-name="@item.Attendee.Name" data-active-new-state="true" data-show-confirmation-alert="true">Activar</button> } </td> </tr> } </tbody> </table> 由脚本加载: var _atteendeesList = "at-attendees-list"; $("#" + _atteendeesList).DataTable({ "paging": false, "info": false, "language": { "search": "Pesquisar:", "info": "Participantes inscritos: _PAGES_" } }); 使用默认的_Layout.cshtml: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>izigo Conference - Gestor de Conteúdos</title> <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" /> <meta name="viewport" content="width=device-width" /> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") </head> <body> <header> <div class="content-wrapper"> <section id="login"> @Html.Partial(MVC.Account.Views._LoginPartial) </section> <div style="padding: 10px;"> @if (Request.IsAuthenticated) { <nav> <ul id="menu"> <li>@Html.ActionLink("Home", MVC.Home.Index())</li> <li>@Html.ActionLink("Participantes", MVC.Attendee.Index())</li> <li>@Html.ActionLink("Check-in", MVC.Checkin.Index())</li> </ul> </nav> } </div> </div> </header> <div id="body"> @RenderSection("featured", required: false) <section class="content-wrapper main-content clear-fix"> @RenderBody() </section> </div> <footer style="padding-left: 25px;"> <div class="content-wrapper"> <div class="float-left"> <p>© @DateTime.Now.Year - <a href="https://www.izigo.pt/conference" target="_blank">izigo Conference</a> - <i>Powered by</i><a href="https://www.izigo.pt" target="_blank">izigo.pt</a></p> </div> </div> </footer> @Scripts.Render("~/bundles/jquery", "~/bundles/iziconference") @RenderSection("scripts", required: false) </body> </html> 研究了 dataTables 库的选项后,我找到了一个创建响应式解决方案的选项: 我已经包含了响应表结构和columnDefs的选项,以选择哪些选项在移动设备中保持可见: $("#" + _atteendeesList).DataTable({ "responsive": true, "columnDefs": [ { responsivePriority: 1, targets: 0 }, { responsivePriority: 2, targets: -1 } ], "paging": false, "info": false, "language": { "search": "Pesquisar:", "info": "Participantes inscritos: _PAGES_" } }); 我还必须在捆绑包中包含数据表扩展的 js 和 css 响应式库(可在此处下载:https://datatables.net/download/): bundles.Add(new ScriptBundle("~/bundles/iziconference").Include( "~/Content/Scripts/datatables.min.js", "~/Content/Scripts/dataTables.responsive.min.js")); // add-on bundles.Add(new StyleBundle("~/Content/css").Include( "~/Content/Styles/datatables.min.css", "~/Content/Styles/responsive.dataTables.min.css"));
android中customView中如何收集Viewmodel StateFlow
android中customView中如何采集StateFlow 我有一个视图模型 类 MyViewModel : ViewModel() { 私有 val _myState = MutableStateFlow(MyState()) val myState:StateFlow android中customView中如何采集StateFlow 我有一个视图模型 class MyViewModel : ViewModel() { private val _myState = MutableStateFlow(MyState()) val myState: StateFlow<MyState> = _myState fun updateMyState(newState: MyState) { _myState.value = newState } } data class MyState( val name: String = "", val age: Int = 0, val isMarried: Boolean = false ) 我能够使用收集活动中的更新数据 lifecycleScope.launchWhenStarted { viewModel.myState.collect { state -> Log.e("collected ", "tateflow: ${state.name}") } } 我们如何根据收集的数据更新自定义视图?我们如何根据这些数据更新自定义视图 您能分享一下在自定义视图中创建 viewModel 的代码吗?你的代码是不是类似这样: private val viewModel: ActivityViewModel by activityViewModels()
我有一个包含以下内容的html字符串: 我有一个包含以下内容的html字符串: <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=windows-1250"> <meta name="spanish press" content="spain, spanish newspaper, news,economy,politics,sports"> <title></title> </head> <body id="body"> <!-- The following code will render a clickable image ad in the page --> <script src="http://www.myscript.com/a"></script> </body> </html> 我需要将该网站显示到 Android 中的网络视图中。 我尝试过这一切: webView.loadDataWithBaseURL(null, txt, "text/html", "UTF-8", null); webView.loadDataWithBaseURL("x-data://base", txt, "text/html", "UTF-8", null); webView.loadDataWithBaseURL("notreal/", txt, "text/htm", "utf-8",null); 我还尝试删除 DOCTYPE 标签: txt=txt.replace("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">", ""); 这些人都没有工作。我刚刚实现了将字符串显示到 webview(html 代码)中,但不是必须使用该 html 代码创建的网站。 出了什么问题? 在 WebView 中加载数据。调用WebView的loadData()方法 wv.loadData(yourData, "text/html", "UTF-8"); 你可以查看这个例子 http://developer.android.com/reference/android/webkit/WebView.html [编辑1] 您应该在 -- " 之前添加 -- \ -- 例如 --> name=\"spanish press\" 下面的字符串对我有用 String webData = "<!DOCTYPE html><head> <meta http-equiv=\"Content-Type\" " + "content=\"text/html; charset=utf-8\"> <html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=windows-1250\">"+ "<meta name=\"spanish press\" content=\"spain, spanish newspaper, news,economy,politics,sports\"><title></title></head><body id=\"body\">"+ "<script src=\"http://www.myscript.com/a\"></script>şlkasşldkasşdksaşdkaşskdşk</body></html>"; 你也可以试试这个 final WebView webView = new WebView(this); webView.loadDataWithBaseURL(null, content, "text/html", "UTF-8", null); 从资产 html 文件中读取 ViewGroup webGroup; String content = readContent("content/ganji.html"); final WebView webView = new WebView(this); webView.loadDataWithBaseURL(null, content, "text/html", "UTF-8", null); webGroup.addView(webView); 我有同样的要求,我是按照以下方式完成的。你也可以试试这个。 使用loadData方法 web.loadData(""" <p style='text-align:center'> <img class='aligncenter size-full wp-image-1607' title='' src="+movImage+" alt='' width='240px' height='180px' /> </p> <p> <center> <U> <H2>"+movName+"("+movYear+")</H2> </U> </center> </p> <p><strong>Director : </strong>"+movDirector+"</p> <p><strong>Producer : </strong>"+movProducer+"</p> <p><strong>Character : </strong>"+movActedAs+"</p> <p><strong>Summary : </strong>"+movAnecdotes+"</p> <p><strong>Synopsis : </strong>"+movSynopsis+"</p> """, "text/html", "UTF-8" ); movDirector movProducer 都是我的字符串变量。 简而言之,我保留了 URL 的自定义样式。 如果您正在 JetpackCompose 中寻找某些内容,这可以帮助您: @Composable fun HtmlTextVisualizerComponent(textFromData: String) { val mimeType = "text/html" val encoding = "UTF-8" LazyColumn( modifier = Modifier .padding( start = 24.dp, end = 24.dp, top = 16.dp, bottom = 24.dp, ), ) { items(1) { val state = rememberWebViewState( url = "data:$mimeType;$encoding,$textFromData", ) val navigator = rememberWebViewNavigator() WebView( state = state, modifier = Modifier.fillMaxSize(), navigator = navigator, onCreated = { it.settings.javaScriptEnabled = true }, ) } } } 一定不要忘记在你的 gradle 中添加依赖项: implementation "com.google.accompanist:accompanist-webview:0.30.1"
jQuery Ajax 在 php 同一页面上传递值 - 更新
如何找回: 如何找回: <div id="test"> <?php if (isset($_POST['sweets'])) { ob_clean(); echo $_POST['sweets']; exit; } ?> </div> <form id="a" action="" method="post"> <select name="sweets" onchange="change()" id="select1"> <option >Chocolate</option> <option selected="selected">Candy</option> <option >Taffy</option> <option >Caramel</option> <option >Fudge</option> <option >Cookie</option> </select> </form> <!-- Script --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script> function change() { var sweets = $("#select1").val(); $.ajax({ type: "POST", data: { sweets: sweets }, success: function(data) { $("#test").html(data); } }); } </script> 将值传递给 php 字符串: $string = $_POST['sweets']; <!-- I'm looking for this: --> 我希望这是可能的。我在 stackoverflow 和 google 上寻找答案,但找不到适合我的目的的答案。 对于同一个页面的ajax/PHP脚本,可以将PHP放在脚本的最前面,当有POST提交数据时以exit结束 为了使其更有意义,您应该返回与您通过 POST 提交的内容相关的内容(这是甜食的类型),作为示例,我们展示其一般定义。我们可以使用 switch,这是用于此目的的常用结构: switch ($string) { case "Chocolate": echo "Chocolate is made from cocoa beans, the dried and fermented seeds of the cacao tree"; break; case "Candy": echo "Candy is a sweet food made from sugar or chocolate, or a piece of this"; break; case "Taffy": echo "Taffy is a type of candy invented in the United States, made by stretching and/or pulling a sticky mass of a soft candy base"; break; case "Caramel": echo "Caramel is made of sugar or syrup heated until it turns brown, used as a flavouring or colouring for food or drink"; break; case "Fudge": echo "Fudge is a dense, rich confection typically made with sugar, milk or cream, butter and chocolate or other flavorings"; break; case "Cookie": echo "A cookie (American English) or biscuit (British English) is a baked snack or dessert that is typically small, flat, and sweet"; break; } exit; } ?> 所以以下是示例代码: <?php if (isset($_POST['sweets'])) { // ob_clean(); $string = $_POST['sweets']; switch ($string) { case "Chocolate": echo "Chocolate is made from cocoa beans, the dried and fermented seeds of the cacao tree"; break; case "Candy": echo "Candy is a sweet food made from sugar or chocolate, or a piece of this"; break; case "Taffy": echo "Taffy is a type of candy invented in the United States, made by stretching and/or pulling a sticky mass of a soft candy base"; break; case "Caramel": echo "Caramel is made of sugar or syrup heated until it turns brown, used as a flavouring or colouring for food or drink"; break; case "Fudge": echo "Fudge is a dense, rich confection typically made with sugar, milk or cream, butter and chocolate or other flavorings"; break; case "Cookie": echo "A cookie (American English) or biscuit (British English) is a baked snack or dessert that is typically small, flat, and sweet"; break; } exit; } ?> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <select name="sweets" onchange="change()" id="select1"> <option value="">Please select</option> <option >Chocolate</option> <option >Candy</option> <option >Taffy</option> <option >Caramel</option> <option >Fudge</option> <option >Cookie</option> </select> <br><br> <div id="test"></div> <script> function change() { var sweets = $("#select1").val(); $.ajax({ type: "POST", data: { sweets: sweets }, success: function(data) { $("#test").html(data); } }); } </script>
嵌套 useFetch 导致 Nuxt 3 中的 Hydration 节点不匹配
在 Nuxt 3 页面内,我通过从 pinia 存储调用操作来获取帖子数据: {{ 发布数据 }} {{ 帖子内容... 在 Nuxt 3 页面内,我通过从 pinia 商店调用操作来获取帖子数据: <template> <div v-if="postData && postContent"> {{ postData }} {{ postContent }} </div> </template> <script setup> const config = useRuntimeConfig() const route = useRoute() const slug = route.params.slug const url = config.public.wpApiUrl const contentStore = useContentStore() await contentStore.fetchPostData({ url, slug }) const postData = contentStore.postData const postContent = contentStore.postContent </script> 那是我的商店: import { defineStore } from 'pinia' export const useContentStore = defineStore('content',{ state: () => ({ postData: null, postContent: null }), actions: { async fetchPostData({ url, slug }) { try { const { data: postData, error } = await useFetch(`${url}/wp/v2/posts`, { query: { slug: slug }, transform(data) { return data.map((post) => ({ id: post.id, title: post.title.rendered, content: post.content.rendered, excerpt: post.excerpt.rendered, date: post.date, slug: post.slug, })); } }) this.postData = postData.value; if (postData && postData.value && postData.value.length && postData.value[0].id) { const {data: postContent} = await useFetch(`${url}/rl/v1/get?id=${postData.value[0].id}`, { method: 'POST', }); this.postContent = postContent.value; } } catch (error) { console.error('Error fetching post data:', error) } } } }); 浏览器中的输出正常,但我在浏览器控制台中收到以下错误: entry.js:54 [Vue warn]: Hydration node mismatch: - rendered on server: <!----> - expected on client: div at <[slug] onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > > at <Anonymous key="/news/hello-world()" vnode= {__v_isVNode: true, __v_skip: true, type: {…}, props: {…}, key: null, …} route= {fullPath: '/news/hello-world', hash: '', query: {…}, name: 'news-slug', path: '/news/hello-world', …} ... > at <RouterView name=undefined route=undefined > at <NuxtPage> at <Default ref=Ref< undefined > > at <LayoutLoader key="default" layoutProps= {ref: RefImpl} name="default" > at <NuxtLayoutProvider layoutProps= {ref: RefImpl} key="default" name="default" ... > at <NuxtLayout> at <App key=3 > at <NuxtRoot> 如何解决这个问题? 我尝试在 onMounted 中获取帖子数据,但在这种情况下 postData 和 postContent 保持为空 onMounted(async () => { await contentStore.fetchPostData({ url, slug }) }) 您可以使用 ClientOnly 组件来消除该警告。请参阅文档了解更多信息。 该组件仅在客户端渲染其插槽。
使用 IndexedPointInAreaLocator 和 STRTree(JTS 拓扑套件)无法实现多边形中的点性能
私人列表findZonesForShipPosition(点点){ List zoneDefinitionCacheHits = new ArrayList<>(); strTree.query(point.getEnvelopeIn... private List<ZoneDefinitionCacheMemory> findZonesForShipPosition(Point point) { List<Object> zoneDefinitionCacheHits = new ArrayList<>(); strTree.query(point.getEnvelopeInternal(), zoneDefinitionCacheHits::add); return zoneDefinitionCacheHits.stream() .filter(ZoneDefinitionCacheMemory.class::isInstance) .map(ZoneDefinitionCacheMemory.class::cast) .filter(zoneDefinition -> isPointInsideGeometry(point, zoneDefinition.getGeometry())) .toList(); } private boolean isPointInsideGeometry(Point point, Geometry geometry) { PointOnGeometryLocator pointOnGeometryLocator = new IndexedPointInAreaLocator(geometry); int location = pointOnGeometryLocator.locate(point.getCoordinate()); boolean isInside = location == Location.INTERIOR; return isInside; } 我使用上面的代码来搜索多边形中的点,在查询之前将所有多边形和多边形插入到 strTree 中,并且我还使用 IndexedPointInAreaLocator 在 STR Tree 的顶部添加一个附加过滤器来验证是否给定点是否确实位于几何中。 此外,我的多边形非常大,这意味着某些多边形中有近 160 万个点。 因此,通过此实现,我面临着性能问题,这种方法至少需要 100 毫秒才能完成,这对于我的用例来说是不期望的。 这里可能出现什么问题?或任何以某种方式加快速度的建议。 我的用例:我将获得很多点来检测它们是否位于给定几何形状(多边形和多多边形)的内部或外部 我尝试使用 Polygon.contains(point) 谓词,但它比 IndexedPointInAreaLocator 方法花费更多时间。 如果你的多边形很大(从某种意义上说它们覆盖了很大的区域)或者形状很奇怪。然后,细分它们可能会提高索引性能,请记住索引首先在多边形的边界框上工作,以节省在多边形测试中进行昂贵的点。如果一个点落入许多边界框但只有一个多边形,则索引不会有太大帮助。 Paul Ramsey 的这篇博客文章在 PostGIS 上下文中讨论了这一点,但这里的底层实现是相同的。这个answer将帮助您划分多边形(因为我认为JTS没有细分方法)。 您还可以从 JTS 代码周围使用 GeoTools 中受益,因为这将允许您切换到使用具有内置索引的 PostGIS 或 GeoPackage 数据库,或更简单的 在内存存储中建立索引。
这是我在 Tabs 组件中使用 VUE 2 的旧代码: 创建(){ this.tabs = this.$children; } 标签: .... 这是我在 Tabs 组件中使用 VUE 2 的旧代码: created() { this.tabs = this.$children; } 标签: <Tabs> <Tab title="tab title"> .... </Tab> <Tab title="tab title"> .... </Tab> </Tabs> VUE 3: 如何使用组合 API 获取有关 Tabs 组件中子项的一些信息?获取长度,迭代它们,并创建选项卡标题,...等?有任何想法吗? (使用组合API) 这是我现在的 Vue 3 组件。我使用 Provide 来获取子 Tab 组件中的信息。 <template> <div class="tabs"> <div class="tabs-header"> <div v-for="(tab, index) in tabs" :key="index" @click="selectTab(index)" :class="{'tab-selected': index === selectedIndex}" class="tab" > {{ tab.props.title }} </div> </div> <slot></slot> </div> </template> <script lang="ts"> import {defineComponent, reactive, provide, onMounted, onBeforeMount, toRefs, VNode} from "vue"; interface TabProps { title: string; } export default defineComponent({ name: "Tabs", setup(_, {slots}) { const state = reactive({ selectedIndex: 0, tabs: [] as VNode<TabProps>[], count: 0 }); provide("TabsProvider", state); const selectTab = (i: number) => { state.selectedIndex = i; }; onBeforeMount(() => { if (slots.default) { state.tabs = slots.default().filter((child) => child.type.name === "Tab"); } }); onMounted(() => { selectTab(0); }); return {...toRefs(state), selectTab}; } }); </script> 选项卡组件: <script lang="ts"> export default defineComponent({ name: "Tab", setup() { const index = ref(0); const isActive = ref(false); const tabs = inject("TabsProvider"); watch( () => tabs.selectedIndex, () => { isActive.value = index.value === tabs.selectedIndex; } ); onBeforeMount(() => { index.value = tabs.count; tabs.count++; isActive.value = index.value === tabs.selectedIndex; }); return {index, isActive}; } }); </script> <template> <div class="tab" v-show="isActive"> <slot></slot> </div> </template> 哦伙计们,我解决了: this.$slots.default().filter(child => child.type.name === 'Tab') 对于想要完整代码的人: 标签.vue <template> <div> <div class="tabs"> <ul> <li v-for="tab in tabs" :class="{ 'is-active': tab.isActive }"> <a :href="tab.href" @click="selectTab(tab)">{{ tab.name }}</a> </li> </ul> </div> <div class="tabs-details"> <slot></slot> </div> </div> </template> <script> export default { name: "Tabs", data() { return {tabs: [] }; }, created() { }, methods: { selectTab(selectedTab) { this.tabs.forEach(tab => { tab.isActive = (tab.name == selectedTab.name); }); } } } </script> <style scoped> </style> 标签.vue <template> <div v-show="isActive"><slot></slot></div> </template> <script> export default { name: "Tab", props: { name: { required: true }, selected: { default: false} }, data() { return { isActive: false }; }, computed: { href() { return '#' + this.name.toLowerCase().replace(/ /g, '-'); } }, mounted() { this.isActive = this.selected; }, created() { this.$parent.tabs.push(this); }, } </script> <style scoped> </style> 应用程序.js <template> <Tabs> <Tab :selected="true" :name="'a'"> aa </Tab> <Tab :name="'b'"> bb </Tab> <Tab :name="'c'"> cc </Tab> </Tabs> <template/> 我扫描子元素的解决方案(在对 vue 代码进行大量筛选之后)是这样的。 export function findChildren(parent, matcher) { const found = []; const root = parent.$.subTree; walk(root, child => { if (!matcher || matcher.test(child.$options.name)) { found.push(child); } }); return found; } function walk(vnode, cb) { if (!vnode) return; if (vnode.component) { const proxy = vnode.component.proxy; if (proxy) cb(vnode.component.proxy); walk(vnode.component.subTree, cb); } else if (vnode.shapeFlag & 16) { const vnodes = vnode.children; for (let i = 0; i < vnodes.length; i++) { walk(vnodes[i], cb); } } } 这将返回子组件。我对此的用途是我有一些通用的对话框处理代码,用于搜索子表单元素组件以咨询其有效性状态。 const found = findChildren(this, /^(OSelect|OInput|OInputitems)$/); const invalid = found.filter(input => !input.checkHtml5Validity()); 如果你复制粘贴与我相同的代码 然后只需向“选项卡”组件添加一个创建的方法,该方法将自身添加到其父级的选项卡数组中 created() { this.$parent.tabs.push(this); }, 使用脚本设置语法,您可以使用useSlots:https://vuejs.org/api/sfc-script-setup.html#useslots-useattrs <script setup> import { useSlots, ref, computed } from 'vue'; const props = defineProps({ perPage: { type: Number, required: true, }, }); const slots = useSlots(); const amountToShow = ref(props.perPage); const totalChildrenCount = computed(() => slots.default()[0].children.length); const childrenToShow = computed(() => slots.default()[0].children.slice(0, amountToShow.value)); </script> <template> <component :is="child" v-for="(child, index) in childrenToShow" :key="`show-more-${child.key}-${index}`" ></component> </template> 我对 Ingrid Oberbüchler 的组件做了一个小改进,因为它不支持热重载/动态选项卡。 在 Tab.vue 中: onBeforeMount(() => { // ... }) onBeforeUnmount(() => { tabs.count-- }) 在 Tabs.vue 中: const selectTab = // ... // ... watch( () => state.count, () => { if (slots.default) { state.tabs = slots.default().filter((child) => child.type.name === "Tab") } } ) 我也遇到了同样的问题,在做了很多研究并问自己为什么他们删除了$children之后,我发现他们创建了一个更好、更优雅的替代方案。 这是关于动态组件的。 (<component: is =" currentTabComponent "> </component>). 我在这里找到的信息: https://v3.vuejs.org/guide/component-basics.html#dynamic-components 希望这对你有用,向大家问好!! 我发现这个更新的 Vue3 教程使用 Vue 插槽构建可重用的选项卡组件对于与我相关的解释非常有帮助。 它使用 ref、provide 和ject 来替换我遇到同样问题的this.tabs = this.$children;。 我一直在遵循我最初发现的构建选项卡组件(Vue2)的教程的早期版本创建您自己的可重用 Vue 选项卡组件。 根据 Vue 文档,假设您在 Tabs 组件下有一个默认插槽,您可以直接在模板中访问该插槽的子级,如下所示: // Tabs component <template> <div v-if="$slots && $slots.default && $slots.default()[0]" class="tabs-container"> <button v-for="(tab, index) in getTabs($slots.default()[0].children)" :key="index" :class="{ active: modelValue === index }" @click="$emit('update:model-value', index)" > <span> {{ tab.props.title }} </span> </button> </div> <slot></slot> </template> <script setup> defineProps({ modelValue: Number }) defineEmits(['update:model-value']) const getTabs = tabs => { if (Array.isArray(tabs)) { return tabs.filter(tab => tab.type.name === 'Tab') } else { return [] } </script> <style> ... </style> 并且 Tab 组件可能类似于: // Tab component <template> <div v-show="active"> <slot></slot> </div> </template> <script> export default { name: 'Tab' } </script> <script setup> defineProps({ active: Boolean, title: String }) </script> 实现应类似于以下内容(考虑一组对象,每个部分一个,带有 title 和 component): ... <tabs v-model="active"> <tab v-for="(section, index) in sections" :key="index" :title="section.title" :active="index === active" > <component :is="section.component" ></component> </app-tab> </app-tabs> ... <script setup> import { ref } from 'vue' const active = ref(0) </script> 另一种方法是使用 useSlots,如 Vue 文档(上面的链接)中所述。 在 3.x 中,$children 属性已被删除并且不再受支持。相反,如果您需要访问子组件实例,他们建议使用 $refs。作为数组 https://v3-migration.vuejs.org/writing-changes/children.html#_2-x-syntax 在 3.x 版本中,$children 已被删除且不再受支持。使用 ref 访问子实例。 <script setup> import { ref, onMounted } from 'vue' import ChildComponent from './ChildComponent .vue' const child = ref(null) onMounted(() => { console.log(child.value) // log an instance of <Child /> }) </script> <template> <ChildComponent ref="child" /> </template> 详细信息:https://vuejs.org/guide/essentials/template-refs.html#template-refs 基于@Urkle的回答: /** * walks a node down * @param vnode * @param cb */ export function walk(vnode, cb) { if (!vnode) return; if (vnode.component) { const proxy = vnode.component.proxy; if (proxy) cb(vnode.component.proxy); walk(vnode.component.subTree, cb); } else if (vnode.shapeFlag & 16) { const vnodes = vnode.children; for (let i = 0; i < vnodes.length; i++) { walk(vnodes[i], cb); } } } 除了已接受的答案之外: 而不是 this.$root.$children.forEach(component => {}) 写 walk(this.$root, component => {}) 这就是我让它为我工作的方式。
我有 和 元素,其内容在某些步骤中不应可编辑。 因此,最初我向这些元素添加了一个禁用属性。元素</desc> <question vote="0"> <p>我有 <pre><code><input type="text"></code></pre> 和 <pre><code><textarea></code></pre> 元素,其内容在某些步骤中不应可编辑。</p> <p>所以,最初我为这些元素添加了 <pre><code>disabled</code></pre> 属性。这些元素变得不可编辑并且呈灰色。这个行为很好。</p> <p>但是,它们的内容应该是可选择的,而 <pre><code>disabled</code></pre> 属性避免了这种情况。所以我切换到了 <pre><code>readonly</code></pre> 属性。元素仍然不可编辑,内容可以选择,但不再是灰色的。</p> <p>因此,我正在寻找一种解决方案来包含以下元素:不可编辑、可选择和灰显。</p> <ul> <li>我可以应用一些 CSS,但我更喜欢禁用输入的本机浏览器样式。</li> <li>这些元素不是<pre><code><form></code></pre>的一部分,因此无需担心表单提交。</li> </ul> </question> <answer tick="false" vote="0"> <p>要在不使用disabled属性的情况下实现具有不可编辑、可选择和灰显元素的所需行为,您可以使用CSS和readonly属性的组合。您可以设置只读元素的样式,使其看起来像已禁用,同时保留选择其内容的能力。以下是如何实现此目标的示例:</p> <pre><code>input[readonly], textarea[readonly] { color: #777; /* Set text color to a muted color */ background-color: #eee; /* Set background color to a light grey */ cursor: not-allowed; /* Show a not-allowed cursor to indicate non editable state */ } /* Adjust the style for textareas, if needed */ textarea[readonly] { resize: none; /* Disable textarea resizing */ } </code></pre> <pre><code><!-- Your HTML elements with readonly attribute --> <input type="text" readonly> <textarea readonly></textarea> </code></pre> </answer> </body></html>
错误:在此 BlocBuilder<InternetBloc> Widget<InternetBloc, InternetState> 上方找不到正确的提供程序
我在尝试将 flutter_bloc 集成到 flutter 项目中时遇到错误。 错误:在此 BlocBuilder 上方找不到正确的 Provider 我在尝试将 flutter_bloc 集成到 flutter 项目中时遇到错误。 错误:在此 BlocBuilder Widget 上方找不到正确的提供者 这是我正在使用的代码示例。 internet_state.dart abstract class InternetState{} class InitialInternetState extends InternetState{} class LostConnectionInternetState extends InternetState{} class GainConnectionInternetState extends InternetState{} internet_event.dart abstract class InternetEvent{} class LostConnectionEvent extends InternetEvent{} class GainConnectionEvent extends InternetEvent{} internet_bloc.dart class InternetBloc extends Bloc<InternetEvent, InternetState>{ final Connectivity _connectivity = Connectivity(); StreamSubscription? streamSubscription; InternetBloc() : super(InitialInternetState()){ on<GainConnectionEvent>((event, emit) => emit(GainConnectionInternetState())); on<LostConnectionEvent>((event, emit) => emit(LostConnectionInternetState())); _connectivity.onConnectivityChanged.listen((event) { if(event == ConnectivityResult.mobile || event == ConnectivityResult.wifi){ add(GainConnectionEvent()); } else { add(LostConnectionEvent()); } }); } @override Future<void> close() { streamSubscription?.cancel(); return super.close(); } } main.dart class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatelessWidget { const MyHomePage({super.key, required this.title}); final String title; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(title),), body: SafeArea( child: Center(child: BlocBuilder<InternetBloc, InternetState>( builder: (context, state) { return const Text("hello"); }, )), ),); } } 我明白了。 ======== 小部件库捕获异常====================================== =================== 构建 MediaQuery(MediaQueryData(size: Size(392.7, 783.3), devicePixelRatio: 2.8, textScaler: noscaling, platformBrightness: Brightness.light, padding: EdgeInsets.zero, viewPadding: EdgeInsets.zero, viewInsets: EdgeInsets 时抛出以下 ProviderNotFoundException。零,systemGestureInsets:EdgeInsets(29.8,24.0,29.8,8.0),alwaysUse24HourFormat:假,accessibleNavigation:假,highContrast:假,onOffSwitchLabels:假,disableAnimations:假,invertColors:假,boldText:假,navigationMode:传统,gestureSettings:DeviceGestureSettings (touchSlop:8.0),显示功能:[])): 错误:无法在此 BlocBuilder Widget 之上找到正确的提供程序 发生这种情况是因为您使用了不包含提供程序的 BuildContext 你的选择。有以下几种常见场景: 您在main.dart中添加了一个新的提供程序并执行了热重载。 要修复此问题,请执行热重启。 您尝试阅读的提供商处于不同的路线。 提供商具有“范围”。因此,如果您在路线中插入提供者,那么 其他路线将无法访问该提供商。 您使用了 BuildContext,它是您尝试读取的提供程序的祖先。 确保 BlocBuilder 位于您的 MultiProvider/Provider 下。 当您创建提供程序并尝试立即读取它时,通常会发生这种情况。 例如,代替: Widget build(BuildContext context) { return Provider<Example>( create: (_) => Example(), // Will throw a ProviderNotFoundError, because `context` is associated // to the widget that is the parent of `Provider<Example>` child: Text(context.watch<Example>().toString()), ); } 考虑使用builder,如下所示: Widget build(BuildContext context) { return Provider<Example>( create: (_) => Example(), // we use `builder` to obtain a new `BuildContext` that has access to the provider builder: (context, child) { // No longer throws return Text(context.watch<Example>().toString()); } ); } 如果这些解决方案都不起作用,请考虑在 StackOverflow 上寻求帮助: https://stackoverflow.com/questions/tagged/flutter The relevant error-causing widget was: SafeArea SafeArea:file:///Users/../Projects/flutterTest/bloc_test/lib/main.dart:37:13 When the exception was thrown, this was the stack: #0 Provider._inheritedElementOf (package:provider/src/provider.dart:343:7) #1 Provider.of (package:provider/src/provider.dart:293:30) #2 ReadContext.read (package:provider/src/provider.dart:649:21) #3 _BlocBuilderBaseState.initState (package:flutter_bloc/src/bloc_builder.dart:130:36) #4 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:5602:55) #5 ComponentElement.mount (package:flutter/src/widgets/framework.dart:5447:5) ... Normal element mounting (4 frames) #9 Element.inflateWidget (package:flutter/src/widgets/framework.dart:4326:16) #10 Element.updateChild (package:flutter/src/widgets/framework.dart:3831:20) #11 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #12 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #13 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800:5) #14 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #15 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6743:14) #16 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #17 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #18 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #19 StatelessElement.update (package:flutter/src/widgets/framework.dart:5547:5) #20 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #21 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #22 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #23 StatelessElement.update (package:flutter/src/widgets/framework.dart:5547:5) #24 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #25 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #26 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #27 StatelessElement.update (package:flutter/src/widgets/framework.dart:5547:5) #28 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #29 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #30 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #31 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800:5) #32 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #33 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #34 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #35 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800:5) #36 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #37 Element.updateChildren (package:flutter/src/widgets/framework.dart:3964:32) #38 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6896:17) #39 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #40 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #41 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #42 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800:5) #43 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #44 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #45 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5634:11) #46 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #47 StatefulElement.update (package:flutter/src/widgets/framework.dart:5657:5) #48 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #49 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #50 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5634:11) #51 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #52 StatefulElement.update (package:flutter/src/widgets/framework.dart:5657:5) #53 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #54 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #55 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #56 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800:5) #57 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #58 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #59 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5634:11) #60 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #61 StatefulElement.update (package:flutter/src/widgets/framework.dart:5657:5) #62 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #63 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6743:14) #64 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #65 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #66 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #67 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800:5) #68 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #69 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6743:14) #70 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #71 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #72 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5634:11) #73 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #74 StatefulElement.update (package:flutter/src/widgets/framework.dart:5657:5) #75 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #76 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #77 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5634:11) #78 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #79 StatefulElement.update (package:flutter/src/widgets/framework.dart:5657:5) #80 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #81 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #82 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #83 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800:5) #84 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #85 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #86 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #87 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800:5) #88 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #89 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #90 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #91 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800:5) #92 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #93 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #94 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5634:11) #95 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #96 StatefulElement.update (package:flutter/src/widgets/framework.dart:5657:5) #97 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #98 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #99 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #100 ProxyElement.update (package:flutter/src/widgets/framework.dart:5800:5) #101 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #102 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #103 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5634:11) #104 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #105 StatefulElement.update (package:flutter/src/widgets/framework.dart:5657:5) #106 Element.updateChild (package:flutter/src/widgets/framework.dart:3815:15) #107 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16) #108 Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7) #109 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2895:19) #110 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:984:21) #111 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:457:5) #112 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1325:15) #113 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1255:9) #114 SchedulerBinding.scheduleWarmUpFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:978:7) #118 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12) (elided 3 frames from class _Timer and dart:async-patch) ==================================================================================================== 我不想使用像 MultiProvider 这样的全局提供程序。 您应该在某处创建 InternetBloc 并提供它。 MultiProvider 本身并不是全局的,它只是多个。 更多信息在这里:https://bloclibrary.dev/#/flutterbloccoreconcepts?id=blocprovider 所以,如果您不想使用全局提供程序,它将看起来像这样: class MyHomePage extends StatelessWidget { const MyHomePage({super.key, required this.title}); final String title; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(title), ), body: SafeArea( child: Center( child: BlocProvider<InternetBloc>( create: ( context) => InternetBloc(), child: BlocBuilder<InternetBloc, InternetState>( builder: (context, state) { return const Text("hello"); }, ), ), ), ), ); } } 要使用 BlocBuilder,您需要在 Widget 树中放置一个 BlocProvider。最佳实践是将其放置得尽可能深。在您的情况下,只需将 BlocProvider 放在 BlocBuilder 之上。 此外 MultiProvider / MultiBlocProvider 不是全局 Provider。它只是一个提供多个 Provider/BlocProvider 的便捷小部件。 class MyHomePage extends StatelessWidget { const MyHomePage({super.key, required this.title}); final String title; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(title), ), body: SafeArea( child: Center( // Now everything below that can access the InternetBloc child: BlocProvider<InternetBloc>( create: (_) => InternetBloc(), child: BlocBuilder<InternetBloc, InternetState>( builder: (context, state) { return const Text("hello"); }, ), ), ), ), ); } }
我的页面上有一个带有此 XAML 的按钮: 我的页面上有一个带有此 XAML 的按钮: <Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="50" Height="50" HorizontalContentAlignment="Left" BorderBrush="{x:Null}" Foreground="{x:Null}" Margin="50,0,0,0"> <Button.Style> <Style TargetType="Button"> <Setter Property="Background" Value="Green"/> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" Value="Red"/> </Trigger> </Style.Triggers> </Style> </Button.Style> </Button> 当我将鼠标光标放在按钮上时,按钮的背景更改为默认的 Windows 灰色背景。有什么问题吗? 这是鼠标悬停前后的按钮图片: 之前: 之后: 要删除 MouseOver 上的默认 Button 行为,您需要修改 ControlTemplate。将 Style 定义更改为以下内容应该可以解决问题: <Style TargetType="{x:Type Button}"> <Setter Property="Background" Value="Green"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <Border Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="1"> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/> </Border> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" Value="Red"/> </Trigger> </Style.Triggers> </Style> 编辑:虽然晚了几年,但您实际上可以将边框画笔设置在其中的边框内部。我不知道是否有人指出了这一点,但似乎并非如此...... 到目前为止,所有答案都涉及用其他东西完全替换默认按钮行为。但是,恕我直言,了解可以通过编辑 XAML 元素的现有默认模板来更改仅您关心的部分是有用且重要的。 在处理 WPF 按钮上的悬停效果的情况下,WPF Button 元素中的外观变化是由 Trigger 的默认样式中的 Button 引起的,该样式基于 IsMouseOver 属性并设置顶级的 Background 和 BorderBrush 属性控件模板中的 Border 元素。 Button 元素的背景位于 Border 元素背景下方,因此更改 Button.Background 属性不会阻止看到悬停效果。 通过一些努力,您可以使用自己的 setter 覆盖此行为,但由于您需要影响的元素位于模板中,并且无法在您自己的 XAML 中直接访问,因此该方法将很困难,而且恕我直言过于复杂。 另一种选择是使用图形作为 Content 的 Button 而不是 Background。如果您需要图形上的其他内容,可以将它们与 Grid 组合起来作为内容中的顶级对象。 但是,如果您只是想完全禁用悬停效果(而不仅仅是隐藏它),则可以使用 Visual Studio XAML 设计器: 编辑 XAML 时,选择 “设计” 选项卡。 在“设计”选项卡中,找到您要禁用该效果的按钮。 右键单击该按钮,然后选择“编辑模板/编辑副本...”。在出现的提示中选择要放置新模板资源的位置。这看起来什么也没做,但事实上,设计器将在您指定的位置添加新资源,并更改按钮元素以引用使用这些资源作为按钮模板的样式。 现在,您可以编辑该样式。最简单的方法是删除或注释掉(例如 Ctrl+E、C)<Trigger Property="IsMouseOver" Value="true">...</Trigger> 元素。当然,此时您可以对模板进行任何更改。 完成后,按钮样式将如下所示: <p:Style x:Key="FocusVisual"> <Setter Property="Control.Template"> <Setter.Value> <ControlTemplate> <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/> </ControlTemplate> </Setter.Value> </Setter> </p:Style> <SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/> <SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/> <SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/> <SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/> <SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/> <SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/> <SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/> <SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/> <SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/> <p:Style x:Key="ButtonStyle1" TargetType="{x:Type Button}"> <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/> <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/> <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> <Setter Property="BorderThickness" Value="1"/> <Setter Property="HorizontalContentAlignment" Value="Center"/> <Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="Padding" Value="1"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true"> <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Border> <ControlTemplate.Triggers> <Trigger Property="IsDefaulted" Value="true"> <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> </Trigger> <!--<Trigger Property="IsMouseOver" Value="true"> <Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/> <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/> </Trigger>--> <Trigger Property="IsPressed" Value="true"> <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/> <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/> </Trigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/> <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/> <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </p:Style> (注意:您可以在实际代码中省略 p: XML 命名空间限定…我在这里提供它们只是因为 Stack Overflow XML 代码格式化程序会被没有 XML 完全限定名称的 <Style/> 元素混淆命名空间。) 如果您想对其他按钮应用相同的样式,只需右键单击它们并选择“编辑模板/应用资源”,然后选择刚刚为第一个按钮添加的样式。您甚至可以使用将默认样式应用于 XAML 中的元素的常规技术,将该样式设置为所有按钮的默认样式。 这对我来说效果很好。 按钮样式 <Style x:Key="TransparentStyle" TargetType="{x:Type Button}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Border> <Border.Style> <Style TargetType="{x:Type Border}"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" Value="DarkGoldenrod"/> </Trigger> </Style.Triggers> </Style> </Border.Style> <Grid Background="Transparent"> <ContentPresenter></ContentPresenter> </Grid> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> 按钮 <Button Style="{StaticResource TransparentStyle}" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25" Command="{Binding CloseWindow}"> <Button.Content > <Grid Margin="0 0 0 0"> <Path Data="M0,7 L10,17 M0,17 L10,7" Stroke="Blue" StrokeThickness="2" HorizontalAlignment="Center" Stretch="None" /> </Grid> </Button.Content> </Button> 注释 该按钮显示一个蓝色的小十字,很像用于关闭窗口的十字。 通过将网格的背景设置为“透明”,它会添加一个命中测试,这意味着如果鼠标位于按钮上的任何位置,那么它将起作用。省略此标签,只有当鼠标位于图标中的一条矢量线上方时,按钮才会亮起(这不太有用)。 只想分享我一直在使用的 ResourceDictionary 中的按钮样式。 您可以在样式触发器上自由更改 onHover 背景。 “ColorAnimation To = *您想要的背景(即#FFCEF7A0)”。按钮 BG 也会在 mouseOver 状态后自动恢复到原来的 BG。您甚至可以设置过渡的速度。 资源词典 <Style x:Key="Flat_Button" TargetType="{x:Type Button}"> <Setter Property="Width" Value="100"/> <Setter Property="Height" Value="50"/> <Setter Property="Margin" Value="2"/> <Setter Property="FontFamily" Value="Arial Narrow"/> <Setter Property="FontSize" Value="12px"/> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="Cursor" Value="Hand"/> <Setter Property="Foreground"> <Setter.Value> <SolidColorBrush Opacity="1" Color="White"/> </Setter.Value> </Setter> <Setter Property="Background" > <Setter.Value> <SolidColorBrush Opacity="1" Color="#28C2FF" /> </Setter.Value> </Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <Border x:Name="border" SnapsToDevicePixels="True" BorderThickness="1" Padding="4,2" BorderBrush="Gray" CornerRadius="3" Background="{TemplateBinding Background}"> <Grid> <ContentPresenter Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True" /> </Grid> </Border> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Trigger.EnterActions> <BeginStoryboard> <Storyboard> <ColorAnimation To="#D2F898" Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)" FillBehavior="HoldEnd" Duration="0:0:0.25" AutoReverse="False" RepeatBehavior="1x"/> </Storyboard> </BeginStoryboard> </Trigger.EnterActions> <Trigger.ExitActions> <BeginStoryboard> <Storyboard> <ColorAnimation Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)" FillBehavior="HoldEnd" Duration="0:0:0.25" AutoReverse="False" RepeatBehavior="1x"/> </Storyboard> </BeginStoryboard> </Trigger.ExitActions> </Trigger> </Style.Triggers> </Style> 您所要做的就是调用样式。 实施示例 <Button Style="{StaticResource Flat_Button}" Height="Auto"Width="Auto"> <StackPanel> <TextBlock Text="SAVE" FontFamily="Arial" FontSize="10.667"/> </StackPanel> </Button> 稍微困难一点的答案,使用ControlTemplate并具有动画效果 (改编自https://learn.microsoft.com/en-us/dotnet/framework/wpf/controls/customizing-the-appearance-of-an-existing-control) 在资源字典中为按钮定义一个控件模板,如下所示: <ControlTemplate TargetType="Button" x:Key="testButtonTemplate2"> <Border Name="RootElement"> <Border.Background> <SolidColorBrush x:Name="BorderBrush" Color="Black"/> </Border.Background> <Grid Margin="4" > <Grid.Background> <SolidColorBrush x:Name="ButtonBackground" Color="Aquamarine"/> </Grid.Background> <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="4,5,4,4"/> </Grid> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal"/> <VisualState x:Name="MouseOver"> <Storyboard> <ColorAnimation Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Color" To="Red"/> </Storyboard> </VisualState> <VisualState x:Name="Pressed"> <Storyboard> <ColorAnimation Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Color" To="Red"/> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> </Border> </ControlTemplate> 在您的 XAML 中,您可以将上面的模板用于您的按钮,如下所示: 定义您的按钮 <Button Template="{StaticResource testButtonTemplate2}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White">My button</Button> 希望有帮助 用于更改按钮样式 第一:定义资源样式 <Window.Resources> <Style x:Key="OvergroundIn" TargetType="Button"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Grid Background="#FF16832F"> <ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter> </Grid> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Grid Background="#FF06731F"> <ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Trigger> </Style.Triggers> </Style> <Style x:Key="OvergroundOut" TargetType="Button"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Grid Background="#FFF35E5E"> <ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter> </Grid> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Grid Background="#FFE34E4E"> <ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Trigger> </Style.Triggers> </Style> </Window.Resources> 第二个定义按钮代码 <Border Grid.Column="2" BorderBrush="LightGray" BorderThickness="2" CornerRadius="3" Margin="2,2,2,2" > <Button Name="btnFichar" BorderThickness="0" Click="BtnFichar_Click"> <Button.Content> <Grid> <TextBlock Margin="0,7,0,7" TextAlignment="Center">Fichar</TextBlock> </Grid> </Button.Content> </Button> </Border> 第三个代码 public void ShowStatus() { switch (((MainDto)this.DataContext).State) { case State.IN: this.btnFichar.BorderBrush = new SolidColorBrush(Color.FromRgb(243, 94, 94)); this.btnFichar.Style = Resources["OvergroundIn"] as Style; this.btnFichar.Content = "Fichar Salida"; break; case State.OUT: this.btnFichar.BorderBrush = new SolidColorBrush(Color.FromRgb(76, 106, 83)); this.btnFichar.Style = Resources["OvergroundOut"] as Style; this.btnFichar.Content = "Fichar Entrada"; break; } }