整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          C# + Blazor Web入門實戰(zhàn):私人筆記(8)創(chuàng)建分類編輯組件

          一節(jié)我們實現(xiàn)了分類樹的右鍵菜單彈出,本節(jié)我們繼續(xù)實現(xiàn)數(shù)據(jù)從瀏覽器到數(shù)據(jù)庫的工作。


          完善菜單內(nèi)容

          我們先來豐富右鍵菜單的選項,在Menu控件中添加MenuItem,分別是修改節(jié)點和刪除節(jié)點:

          <Menu Style="@menuStyle">
          ???????<MenuItem OnClick="CreateNode">
          ???????????@menu_create_text
          ???????</MenuItem>
          ???????<MenuItem OnClick="ModifyNode">
          ???????????修改節(jié)點
          ???????</MenuItem>
          ???????<MenuItem OnClick="DeleteNode">
          ???????????刪除節(jié)點
          ???????</MenuItem>
          ???</Menu>

          由于修改和刪除不像創(chuàng)建涉及到不同的名稱,所以菜單文章內(nèi)容直接寫死。事件響應代碼一并復制就好。

          void ModifyNode(MouseEventArgs args)
          {
          menuStyle = "display:none;";
          }
          
          void DeleteNode(MouseEventArgs args)
          {
          menuStyle = "display:none;";
          }

          運行效果:


          創(chuàng)建分類編輯組件

          我們的右鍵菜單現(xiàn)在有了事件觸發(fā),接下來要彈出分類編輯頁面來錄入信息。我們首先需要創(chuàng)建一個名為CategoryEdit.Razor組件,過程跟上一節(jié)我們創(chuàng)建ContextMenuPanel一樣。如下圖:

          這個過程我們以后就不再講了。

          有同學私信問不使用Ant Design組件,直接用Blazor系統(tǒng)的組件可行嗎?我覺得這個問題比較有代表性,所以這個CategoryEdit我就不使用Ant Design的組件來完成。先上完整的代碼吧:

          <div style="width:100%; display:@display;">
          <div class="page">
          <div @onclick="toggle" id="close">X</div>
          <div style="padding: 10px;">
          <ul>
          <li class="item"><span>編碼:</span><input @bind="@Value.Id" /></li>
          ???????????????<li class="item"><span>名稱:</span><input @bind="@Value.Name" /></li>
          ???????????????<li class="item"><span>所屬Id:</span><input @bind="@Value.ParentId" /></li>
          ???????????</ul>
          ???????????<ul>
          ???????????????<li class="item">
          ???????????????????<span>是否有子類:</span>
          ???????????????????<select @bind="@has_child">
          ???????????????????????<option value="1">true</option>
          ???????????????????????<option value="0">false</option>
          ???????????????????</select>
          ???????????????</li>
          ???????????????<li class="item"><span>分類類型:</span><input @bind="@Value.Type" /></li>
          ???????????????<li class="item"><span>顯示順序:</span><input @bind="@Value.ShowOrder" /></li>
          ???????????</ul>
          ???????????<div>
          ???????????????<label>分類描述:</label>
          ???????????????????<textarea style="width:100%; min-height:200px;" @bind=@Value.Description></textarea>
          ???????????????<label>備注:</label>
          ???????????????????<textarea style="width:100%; min-height:200px;" @bind=@Value.Remark></textarea>
          ???????????</div>
          ???????????<button @onclick="save">保存</button>
          ???????</div>
          ???</div>
          </div>
          
          @code {
          ???string display = "none";
          
          ???public void toggle()
          ???{
          ???????display = (display == "none") ? "block" : "none";
          ???}
          
          ???[Parameter]
          ???public EventCallback OnSave { get; set; }
          
          ???[Parameter]
          ???public Model.Category Value { get; set; }
          
          ???int has_child = 0;
          ???void save()
          ???{
          ???????Value.HasChild = (has_child == 0) ? false : true;
          ???????if (OnSave.HasDelegate) OnSave.InvokeAsync();
          ???}
          }

          樣式文件CategoryEdit.razor.css

          .page { width:960px; border: 1px solid #CCC; margin-left:auto; margin-right:auto; }
          .item { width: 280px; list-style:none; display: inline-block; }
          .item span { width: 100px; display: inline-block; }
          #close {
              position: relative;
              text-align: center;
              cursor: pointer;
              background: #FCC;
              float: right;
              width: 20px;
              height: 20px;
          }
              #close:hover {
                  background-color: #F00;
              }

          上部分為html元素標簽,具體標簽和布局就不展開講了。

          @display是引用下面code中的變量,只要display的值變化,這里就會隨之生效;

          @onclick是綁定click事件;用到了兩處,一個是右上角的關(guān)閉按鈕,一個是下方的保存按鈕;

          @bind="@Value.Id跟上面的@display類似,只是這個用于控件,控件的值與變量值雙向綁定;

          public void toggle()是切換是否顯示的方法,默認隱藏,調(diào)用一次就切換一次;

          [Parameter]是定義CategoryEdit組件的屬性;

          public EventCallback OnSave是聲明一個OnSave的函數(shù)作為回調(diào);

          public Model.Category Value是要編輯或新建的Category數(shù)據(jù)實體;

          int has_child是對應Model.Category中的HasChild,在標準select及option中無法直接綁定bool類型的熟知,所以用has_child來作為媒介;

          void save()則是保存函數(shù),做數(shù)據(jù)處理后回調(diào)OnSave;

          css文件在blazor中是隔離的,即聲明一個跟razor組件同名的css文件,它就會從屬于這個razor組件,只對這個razor生效,這樣可以很好的解決不同css文件命名相互沖突的問題。

          上面完全都是靠代碼堆的,這里有點沒想明白為什么微軟不延續(xù)winform、webform的所見即所得的方式,哪怕是有個設(shè)計視圖瀏覽也好。難道是技術(shù)上過于復雜嗎?目前以Blazor這種開發(fā)方式,想要看到修改效果,哪怕是只調(diào)一個顏色,都只能重新編譯運行才能看到效果,非常影響開發(fā)效率。以前webform的那種,改前端根本需要編譯,重新刷新頁面就好。希望這里未來能有改進。


          調(diào)用分類編輯組件

          CategoryEdit組件設(shè)計完成后,我們就可以在Index.razor中使用它了

          <CategoryEdit @ref="categoryEditor" Value="@curCategory" OnSave="@SaveCategory"></CategoryEdit>
          @code {
          CategoryEdit categoryEditor;
          Model.Category curCategory = new Model.Category();
          void SaveCategory()
          {
          }
          }


          我們只需要這幾行代碼就夠了。對屬性賦值,響應事件。然后我們先來看下效果:

          我們可以看到,調(diào)用完成后,在Index.razor中的SaveCategory函數(shù)中,curCategory中的值就都有了。實際上我們用的控件庫,比如Ant Design也都是這樣一步一步來完成的,只要有時間、有耐心,啥都不是事。


          到目前為止,我們已經(jīng)完成了前端的數(shù)據(jù)準備,接下來我們就是要通過WebAPI正式向服務器提交信息了。在一般的公司中,前端和后端都是分開不同團隊來做的,后端做完提供接口,前端按照接口規(guī)范進行調(diào)用。那我們接下來的事情就是要做后端的工作了,考慮到同樣編碼內(nèi)容較多,這節(jié)暫時到這里,我們下節(jié)繼續(xù)。

          ----------------------------------------------------

          本教程項目源碼已作為開源項目加入到Gitee,代碼內(nèi)容會隨教程實時更新,大家有興趣的話可以關(guān)注我,以獲得最及時的更新。私信:

          私人日記 可以獲取相關(guān)鏈接;

          大家閱讀過程中有哪些看不懂或未盡興的地方,可以在評論區(qū)留言,我會先記下來在后續(xù)的教程中找機會再說。

          教程有幫助的話請大家?guī)兔﹃P(guān)注、轉(zhuǎn)發(fā)、擴散,能不能開專欄還需要你們的支持!

          目中使用到了 updatePanel 和jquery-easyui 。

          使用updatepanel的好處自然是頁面不刷新,用戶感覺比較好,同時也減少了一部分數(shù)據(jù)量的傳輸。

          使用easyui 的好處除了界面還不錯之外,也因為使用方便。

          <div class="easyui-tabs" style="width: 300px"> <div title="搜索"> ...</div> <div title="選擇">...</div> <div title="返回">...</div></div>只要給他定義個相應的class 就能實現(xiàn)各種效果。

          但是,把它放在updatepanel里面,且不是首次就讓他顯示出來的話就出故障了。

          例如:

          代碼<asp:MultiView ID="MultiView1" runat="server"> <asp:View ID="View1" runat="server"> <div class="easyui-tabs" style="width: 300px"> <div title="搜索"> ...</div> <div title="選擇"> ...</div> <div title="返回"> ...</div> </div> </asp:View> <asp:View ID="View2" runat="server"> <div class="easyui-tabs" style="width: 300px"> <div title="搜索"> ...</div> <div title="選擇"> ...</div> <div title="返回"> ...</div> </div> </asp:View> </asp:MultiView>在multipleView里面定義兩個一樣的view,內(nèi)容也一樣。并把 MultiView1放到updatepanel里面。

          然后設(shè)置他顯示第一個view

          MultiView1.ActiveViewIndex =0;瀏覽一下。顯示正常。但是當我們改變view的顯示時,例如把上面的改成 MultiView1.ActiveViewIndex =1;那么第二個veiw的效果就全無了。

          到jquery.easyui.min.js 里找原因。看到了這么一句

          r=$(".easyui-tabs",_1ec);if(r.length){r.tabs();大概就是在網(wǎng)頁加載完后,尋找class定義為easyui-tabs 的層。并把效果附加給他。

          那么可以想象,當頁面加載時,我們顯示的是第一個view,那么js就找到view里的層,并賦予其效果。

          然后我們在updatepanel里更新了顯示的view,內(nèi)容雖然切換到了第二個view了。但是頁面沒有重新加載,上面的js代碼沒有對新的view執(zhí)行改變。

          所以決策就是當updatepanel回發(fā)后重新執(zhí)行js代碼。

          在頁面定義一個重新綁定的函數(shù)。

          function EndRequestHandler() { $(".easyui-tabs").tabs(); }再定義一個事件。 function reload() { Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler); }add_endRequestPageRequestManager 類是一個管理瀏覽器中服務器 UpdatePanel 控件的部分頁更新。此外,還定義一些屬性、事件和方法,用以通過客戶端腳本對網(wǎng)頁進行自定義。通過調(diào)用 getInstance 方法來得到 PageRequestManager 類的實例。然后通過 add_endRequest 方法來綁定 endRequest 事件(異步回發(fā)完成,并且控制權(quán)返回到瀏覽器之后引發(fā))。這樣以后,每次updatepanel發(fā)生回調(diào)后,都會觸發(fā)EndRequestHandler()函數(shù)。重新綁定一次效果。$(document).ready(function() { reload(); })失效問題就解決了。

          原文:http://www.cnblogs.com/topdog/archive/2010/04/11/1709413.html

          上文---磁性窗體的設(shè)計01-C#學習進階

          實例說明

          在多媒體播放軟件中,經(jīng)常會遇到一種情況,即當拖動其中一個窗體(主窗體)時,其他的窗體(子窗體)也可以隨著該窗體移動,當拖動子窗體時,其他窗體將不跟隨移動。這就是磁性窗體。本實例將制作一個磁性窗體,當拖動主窗體移動時,兩個子窗體如果相連,則跟隨移動。

          開發(fā)步驟

          (1)新建一個Windows應用程序,將其命名為“磁性窗體的設(shè)計”,創(chuàng)建3個窗體,分別命名為Frm_Play、Frm_ListBox和Frm_Libretto,將這3個窗體的FormBorderStyle屬性設(shè)置為None。

          (2)在Frm_Play窗體中添加兩個Panel控件,分別命名為panel_Title和panel_Close,并將panel_Title控件的Dock屬性設(shè)置為Top。

          說明:Frm_ListBox和Frm_Libretto窗體中所用到控件及其設(shè)置與Frm_Play窗體相同,在這里不作詳解。

          (3)主要程序代碼。

          磁性窗體的設(shè)置實際上就是將相關(guān)聯(lián)的窗體位置和大小記錄在公共類FrmClass中,然后在移動窗體時,通過已記錄的窗體信息,實現(xiàn)窗體的磁性效果。

          下面以Frm_Play窗體為例,介紹磁性窗體的實現(xiàn)過程。

          在Frm_Play窗體標題欄上按下鼠標時,獲取其他兩個窗體的相關(guān)信息(這兩個窗體與該窗體具有磁性效果)。代碼如下:

          private void panel_Title_MouseDown(object sender, MouseEventArgs e)
          
          {
          
              int Tem_Y = 0;
          
              if (e.Button == MouseButtons.Left)                                                       //按下的是否為鼠標左鍵
          
              {
          
                  Cla_FrmClass.FrmBackCheck();//檢測各窗體是否連在一起
          
                  Tem_Y = e.Y;
          
                  FrmClass.FrmPoint = new Point(e.X, Tem_Y);                        //獲取鼠標在窗體上的位置,用于磁性窗體
          
                  FrmClass.CPoint = new Point(-e.X, -Tem_Y);                         //獲取鼠標在屏幕上的位置,用于窗體的移動
          
                  if (FrmClass.Example_List_AdhereTo)                                    //如果與frm_ListBox窗體相連接
          
                  {
          
                      Cla_FrmClass.FrmDistanceJob(this, FrmClass.F_List);                    //計算窗體的距離差
          
                      if (FrmClass.Example_Assistant_AdhereTo)                      //兩個輔窗體是否連接在一起
          
                      {
          
                          Cla_FrmClass.FrmDistanceJob(this, FrmClass.F_Libretto);       //計算窗體的距離差
          
                      }
          
                  }
          
                  if (FrmClass.Example_Libretto_AdhereTo) //如果與frm_ Libretto窗體相連接
          
                  {
          
                      Cla_FrmClass.FrmDistanceJob(this, FrmClass.F_Libretto);              //計算窗體的距離差
          
                      if (FrmClass.Example_Assistant_AdhereTo)                            //兩個輔窗體是否連接在一起
          
                      {
          
                          Cla_FrmClass.FrmDistanceJob(this, FrmClass.F_List);            //計算窗體的距離差
          
                      }
          
                  }
          
              }
          
          }
          
          

          未完待續(xù)。。。。


          主站蜘蛛池模板: 亚洲狠狠狠一区二区三区| 国产成人精品久久一区二区三区| 一本大道东京热无码一区| 精品视频一区二区三区在线观看| 成人国产精品一区二区网站公司| 91久久精一区二区三区大全| 精品国产一区二区三区av片| 国产一区二区三区高清在线观看| 国产精品久久一区二区三区| 国产一区二区三区在线2021| 国产一区二区精品久久91| 中文字幕日韩精品一区二区三区| 国产美女精品一区二区三区| 国产一区二区精品在线观看| 精产国品一区二区三产区| 亚洲一区精品中文字幕| 国产一区三区三区| 国产成人精品一区二三区 | 国产一区二区三区高清视频 | 中文字幕精品一区二区日本| 国产精久久一区二区三区| 国产精品福利一区| 亚洲高清毛片一区二区| 国产免费一区二区三区| 人妻体内射精一区二区三区| 久久久久久人妻一区精品| 日韩人妻无码一区二区三区 | 亚洲日本中文字幕一区二区三区| 久久中文字幕无码一区二区 | 国模吧一区二区三区精品视频| 少妇激情av一区二区| 国产成人一区二区三区在线观看| 美女福利视频一区二区| 风流老熟女一区二区三区| 无码一区二区三区亚洲人妻| 久久久久人妻精品一区三寸| 久久人妻无码一区二区| 在线|一区二区三区| 暖暖免费高清日本一区二区三区| 国产乱码精品一区二区三区麻豆| 欧亚精品一区三区免费|