程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> wpf控件設計時支持(3)

wpf控件設計時支持(3)

編輯:關於.NET

wpf設計時調試

編輯模型

裝飾器

1.wpf設計時調試

為了更好的了解wpf設計時框架,那麼調試則非常重要,通過以下配置可以調試控件的設計時代碼

(1)將啟動項目配置成外部的visual studio ide啟動程序devenv.exe

(2)F5啟動調試然後會打開一個新的visual studio ide,這個時候要記得重新打開你要調試的那個項目.

以上兩個步驟就可以實現設計時調試了

2.編輯模型體系

當選中某些控件出現的設計時,這個選中的控件便成了可編輯的對象. 設計環境會傳回一個ModelItem的類,這個類可以幫助你更改控件視圖,用於交互.這裡的做法與直接更改wpf控件有些不同,如直接改變wpf一個控件的一個屬性

this.Content = "Hello";

在設計環境下,也可以獲取到處在編輯狀態的控件,若采取上面的做法,雖可以變更控件的視圖,但卻未變更控件在xaml的更改.

設計環境下所有控件的更改都封裝在ModelItem類中.做法如下

//selectedContent's Type is ModelItem
selectedContent.Properties["Content"].SetValue("Hello");
//selectedContent.Properties[ContentControl.ContentProperty].SetValue("Hello");

selectedContent類型是ModelItem,其中用Properties索引值獲取屬性,有兩種方式獲取屬性,字符串和靜態項屬性

在上篇介紹過控件上下文菜單的設計時做法,我們以此為基礎做個示例,以ContentControl為例,如下圖

共有4個操作,SetHello和SetRedForeground用於測試ModelItem變更控件視圖的功能,

第三個和第四個菜單用於測試變更時事務的操作.(即要麼全過,要麼全不過)

以下為詳細代碼

public class ContentMenuProvider : PrimarySelectionContextMenuProvider
  {
    //略去構造函數添加MenuAcion的代碼
    void ModelEditingScopeFailMenuAction_Execute(object sender, MenuActionEventArgs e)
    {
      ModelItem selectedContent = e.Selection.PrimarySelection;
      using (ModelEditingScope scope = selectedContent.BeginEdit("test"))
      {
        //selectedContent's Type is ModelItem
        selectedContent.Properties["Content"].SetValue("TextModelEditingScope");
        //wrong
        selectedContent.Properties["Foreground"].SetValue("Red");
        scope.Complete();
      }
    }
    void ModelEditingScopeMenuAction_Execute(object sender, MenuActionEventArgs e)
    {
      ModelItem selectedContent = e.Selection.PrimarySelection;
      using (ModelEditingScope scope = selectedContent.BeginEdit("test"))
      {
        selectedContent.Properties["Content"].SetValue("TextModelEditingScope");
        selectedContent.Properties["Foreground"].SetValue(Brushes.Green);
        scope.Complete();
      }
    }
    void SetRedForegroundMenuAction_Execute(object sender, MenuActionEventArgs e)
    {
      ModelItem selectedContent = e.Selection.PrimarySelection;
      selectedContent.Properties["Foreground"].SetValue(Brushes.Red);
      selectedContent.Properties[Control.ForegroundProperty].SetValue(Brushes.Red);
    }
    void SetHelloMenuAction_Execute(object sender, MenuActionEventArgs e)
    {
      ModelItem selectedContent = e.Selection.PrimarySelection;
      //ContentControl element = selectedContent.View as ContentControl;
      //selectedContent.Content = "hello";
      selectedContent.Properties["Content"].SetValue("Hello");
    }
  }

這裡ModelItem通過MenuActionEventArgs傳遞進來.當需要事務支持時,則需要用到ModelEditingScope對象,通過ModelItem的BeginEdit方法,當全部變更完成時,則調用ModelEditingScope的Complete方法.

這裡可以知道ModelItem是設計器對控件做出所有的變更的一個封裝,也是wpf控件設計器的一個基礎.上面介紹通過Properties索引值變更視圖,具體ModelItem其他的功能可以參考msdn相關文檔.

3.裝飾器

上圖是asp.net裡面GridView控件的一個設計視圖,右側的可視化面板到了wpf控件的設計時就稱為裝飾器,那麼這個裝飾器其實就是wpf的控件,實現可視化界面對於使用者而言非常重要,可以了解該控件的常用功能,也省卻了一些開發時間.不過目前wpf內置控件似乎沒一個控件是具有這一功能的,只能希望下版visual studio對wpf控件時做的更好了,可怕的是我們自己無法擴展內置控件的設計時,只能等著微軟來做,最可怕的是visual studio 2010把wpf設計時部分的api全變掉,那麼這裡就全白寫了.

裝飾器功能由AdornerProvider提供,我們從內置提供的PrimarySelectionAdornerProvider類派生一個裝飾器.

派生類需要重寫以上兩個方法,當選中該設計器相關控件時,會調用Activate方法,離開時調用Deactivate方法.為了介紹裝飾器的使用方法.示例將盡量簡單,以介紹裝飾器功能.

一般情況下,裝飾器需要一下幾個步驟

(1)定義一個AdornerPanel對象,並把控件相關裝飾器添加到AdornerPanel中,然後將這個裝飾器容器添加到AdornerProvider的Adorners屬性中,這項操作在Activate方法中完成.

protected override void Activate(ModelItem item, DependencyObject view)
{
  Slider opacitySlider = new Slider();
  opacitySlider.Background = Brushes.Red;
  AdornerPanel myPanel = new AdornerPanel();
  myPanel.Children.Add(opacitySlider);
  Adorners.Add(myPanel);
  base.Activate(item, view);
}

注意Activate方法也將ModelItem傳遞進來,就意味著通過裝飾器的方式也可以變更控件視圖

(2)定位裝飾器

再來看asp.net的GridView的設計時面板,其出現在控件的右側,wpf設計時裝飾器體系允許變更裝飾器位置,上面做的第一個步驟並無法在視圖上看到控件的裝飾器,那是因為裝飾器的定位問題.這個步驟必須完成.

這項工作由AdornerPlacementCollection對象來完成,再通過AdornerPanel的靜態方法SetPlacements來設置裝飾器的位置.

我們來看一下AdornerPlacementCollection的幾個方法,初看會比較暈,無法判斷幾個方法的區別

以上8個方法可以看做4個方法,都是與高度寬度有關的.下面以圖來說明,我們定義的控件裝飾器是一個Slider控件.目前只用於演示作用,它做不了什麼其他事情.

以上是原控件,裝飾器建立在此基礎之上,這裡說明一下上面8個方法的參數,都是一致的,第一個是倍數因子,第二個偏移量

(1)設置容器大小

為了演示,所以裝飾器控件以紅色背景標記,以下代碼添加在Activate方法後面,SizeRelativeToContentWidth && Height方法設置裝飾器容器的大小,設置寬度和高度為控件內容高度和寬度的1倍

相應代碼

AdornerPlacementCollection placement = new AdornerPlacementCollection();
placement.SizeRelativeToContentWidth(1, 0);
placement.SizeRelativeToContentHeight(1, 0);
AdornerPanel.SetPlacements(opacitySlider, placement);

(2)變更裝飾器位置(PositionRelativeToAdornerWidth方法),倍數參數為正數則向右移,負數則向左移

代碼變更為

AdornerPlacementCollection placement = new AdornerPlacementCollection();
placement.SizeRelativeToContentWidth(1, 0);
placement.SizeRelativeToContentHeight(1, 0);
placement.PositionRelativeToAdornerWidth(1, 0);
AdornerPanel.SetPlacements(opacitySlider, placement);

(3)DesiredWidth和DesiredHeight,注意在設計時,控件與容器之間也有著間距,如下紅圈

SizeRelativeToAdornerDesiredWidth方法用於調整裝飾器的DesiredWidth.看下圖黃色紅圈的位置變更,裝飾器向右側移動一個DesiredWidth,並寬度添加一個DesiredWidth.

代碼變更為

AdornerPlacementCollection placement = new AdornerPlacementCollection();
placement.SizeRelativeToContentWidth(1, 0);
placement.SizeRelativeToContentHeight(1, 0);
placement.PositionRelativeToAdornerWidth(1, 0);
placement.SizeRelativeToAdornerDesiredWidth(1, 0);
AdornerPanel.SetPlacements(opacitySlider, placement);

注意PositionRelativeToAdornerWidth方法變更為PositionRelativeToContentWidth方法,那麼SizeRelativeToAdornerDesiredWidth方法只會使裝飾器寬度變更,而位置則不做變更.如下圖

代碼變更為

AdornerPlacementCollection placement = new AdornerPlacementCollection();
placement.SizeRelativeToContentWidth(1, 0);
placement.SizeRelativeToContentHeight(1, 0);
//placement.PositionRelativeToAdornerWidth(1, 0);
placement.PositionRelativeToContentWidth(1, 0);
placement.SizeRelativeToAdornerDesiredWidth(5, 0);
AdornerPanel.SetPlacements(opacitySlider, placement);

一邊情況下不設置容器高度,因為控件的高度是不確定的,所以現在調整如下

現在最終代碼變更為

AdornerPlacementCollection placement = new AdornerPlacementCollection();
placement.SizeRelativeToContentWidth(1, 0);
placement.PositionRelativeToAdornerWidth(1, 0);
placement.SizeRelativeToAdornerDesiredHeight(1, 0);
AdornerPanel.SetPlacements(opacitySlider, placement);

上面方法可以做多次嘗試,便於好的理解.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved