拖放概觀
更新:2007 年 11 月
本主題提供 Windows Presentation Foundation (WPF) 應用程式中之拖放支援的概觀。拖放通常是指一種使用者介面 (UI) 互動方法,牽涉到使用滑鼠 (或某個其他指標裝置) 選取一個或多個物件,然後將這些物件拖曳到 UI 中某個所要的置放目標,再放置這些物件。
這個主題包含下列章節。
- WPF 中的拖放支援
- 資料與資料物件
- 拖放事件
- 使用資料物件
- 相關主題
WPF 中的拖放支援
拖放作業通常會牽涉到兩個單位:被拖曳物件原本所在的拖曳來源,以及接收被放置物件的置放目標。拖曳來源與置放目標可以是同一個應用程式,也可以是不同的應用程式。
拖放可以操作的物件類型與數目完全是隨意的,透過拖放作業操作的較常見物件包括一個或多個檔案或資料夾,以及內容選取範圍。拖放作業期間執行的特定動作是應用程式所特有的,而且常由內容決定。例如,從一個資料夾將檔案選取範圍拖曳到相同儲存裝置的另一個資料夾,此動作預設會移動檔案。然而從通用命名慣例 (UNC) 共用拖曳檔案到本機資料夾,依預設會複製檔案。WPF 所提供的拖放機能具有高度彈性與可自訂的設計,可支援各式各樣的拖放情節。拖放支援在單一應用程式中或不同的應用程式間操作物件,也完全支援 WPF 應用程式與其他 Windows 應用程式之間的拖放。拖放屬於比較常見的資料傳輸方式;除了拖放之外,資料傳輸方式還包括使用系統剪貼簿來進行複製和貼上作業。
安全性提示:OLE 拖放在網際網路區域中無法運作。
資料與資料物件
在拖放作業中傳輸的資料,會儲存在資料物件中。就概念而言,資料物件由下列一組或多組項目組成:
包含實際資料的 Object,以及
對應的資料格式識別項
資料本身可包含任何能以基底 Object 表示的項目。對應的資料格式是字串或 Type,可提示資料是哪一種格式的相關資訊。資料物件支援裝載多個資料-資料格式組,這樣可讓單一資料物件提供多種格式的資料。
所有資料物件都必須實作 IDataObject 介面,這個介面可提供下列標準方法集以啟用並加速資料傳輸。
方法 |
摘要 |
---|---|
以指定的資料格式擷取資料物件。 |
|
檢查資料是否以指定的格式儲存,或是否可轉換成指定的格式。 |
|
傳回格式清單,這個資料物件中的資料是以這些格式儲存,或是可以轉換成這些格式。 |
|
將指定的資料儲存到這個資料物件中。 |
WPF 提供 DataObject 類別中的 IDataObject 基本實作 (Implementation),內建 DataObject 類別對於許多常見的資料傳輸案例已經夠用。
如需隨 WPF 提供之預先定義資料格式的詳細資訊,請參閱 DataFormats 類別參考主題。
資料物件通常包括一項在擷取資料時會將以某種格式儲存的資料自動轉換為另一種格式的機能,這項機能稱為自動轉換。
查詢資料物件中可用的資料格式時,可以藉由呼叫 GetFormats(Boolean) 或 GetDataPresent(String, Boolean) 方法並指定 autoConvert 參數為 false,從原生資料格式中篩選可自動轉換的資料格式。使用 SetData(String, Object, Boolean) 方法將資料加入至資料物件時,可以將 autoConvert 參數設定為 false 以禁止自動轉換資料。
拖放事件
拖放作業支援事件驅動模式。拖曳來源和置放目標都使用標準事件集來處理拖放作業。下表摘要列出標準的拖放事件。
拖曳來源事件
事件 |
摘要 |
---|---|
當拖放作業啟動時會發生這個事件,這個事件可讓置放目標傳送回應資訊給拖曳來源。拖曳來源通常會使用此項回應來動態調整滑鼠指標的外觀,以提供回應給使用者。這是反昇事件。 |
|
當鍵盤或滑鼠按鈕狀態於拖放作業期間內變更時會發生這個事件,這個事件可讓置放來源根據按鍵/按鈕狀態取消拖放作業。這是反昇事件。 |
|
GiveFeedback 的通道版本。 |
|
QueryContinueDrag 的通道版本。 |
置放目標事件
事件 |
摘要 |
---|---|
當物件被拖曳入置放目標界限內時會發生這個事件。這是反昇事件。 |
|
此事件在物件被拖曳出置放目標界限時發生。這是反昇事件。 |
|
當於置放目標界限內拖曳 (移動) 物件時會發生這個事件。這是反昇事件。 |
|
當物件放入置放目標時會發生這個事件。這是反昇事件。 |
|
DragEnter 的通道版本。 |
|
DragLeave 的通道版本。 |
|
DragOver 的通道版本。 |
|
Drop 的通道版本。 |
使用資料物件
本節說明建立和使用資料物件的常用技術。
使用 DataObject 建構函式
DataObject 類別提供數個多載建構函式,可協助以單一資料-資料格式組填入新 DataObject 執行個體。
下列範例程式碼會建立新的資料物件,並使用其中一個多載建構函式 (DataObject(String, Object)) 以用字串和指定的資料格式初始化資料物件。在這個案例中,資料格式是以字串指定。DataFormats 類別可提供一組預先定義的型別字串。預設會允許對儲存的資料進行自動轉換。
string stringData = "Some string data to store...";
string dataFormat = DataFormats.UnicodeText;
DataObject dataObject = new DataObject(dataFormat, stringData);
如需建立資料物件的其他範例程式碼,請參閱 HOW TO:建立資料物件。
以多種格式儲存資料
一個資料物件可以儲存多種格式的資料。比起只代表一種資料格式,在單一資料物件中策略性使用多個資料格式,可以讓資料物件能夠適用於更多種類的置放目標。請注意,一般而言,拖曳來源一定不知道可能的置放目標會使用的資料格式。
下列範例顯示如何使用 SetData(String, Object) 方法,以多種格式將資料加入至資料物件。
DataObject dataObject = new DataObject();
string sourceData = "Some string data to store...";
// Encode the source string into Unicode byte arrays.
byte[] unicodeText = Encoding.Unicode.GetBytes(sourceData); // UTF-16
byte[] utf8Text = Encoding.UTF8.GetBytes(sourceData);
byte[] utf32Text = Encoding.UTF32.GetBytes(sourceData);
// The DataFormats class does not provide data format fields for denoting
// UTF-32 and UTF-8, which are seldom used in practice; the following strings
// will be used to identify these "custom" data formats.
string utf32DataFormat = "UTF-32";
string utf8DataFormat = "UTF-8";
// Store the text in the data object, letting the data object choose
// the data format (which will be DataFormats.Text in this case).
dataObject.SetData(sourceData);
// Store the Unicode text in the data object. Text data can be automatically
// converted to Unicode (UTF-16 / UCS-2) format on extraction from the data object;
// Therefore, explicitly converting the source text to Unicode is generally unnecessary, and
// is done here as an exercise only.
dataObject.SetData(DataFormats.UnicodeText, unicodeText);
// Store the UTF-8 text in the data object...
dataObject.SetData(utf8DataFormat, utf8Text);
// Store the UTF-32 text in the data object...
dataObject.SetData(utf32DataFormat, utf32Text);
查詢資料物件的可用格式
因為單一資料物件可包含任意數量的資料格式,所以資料物件附有能擷取可用資料格式清單的機能。
下列範例程式碼會使用 GetFormats 多載取得字串陣列,這個字串陣列表示資料物件中所有可用的資料格式 (包括原生格式和可自動轉換的格式)。
DataObject dataObject = new DataObject("Some string data to store...");
// Get an array of strings, each string denoting a data format
// that is available in the data object. This overload of GetDataFormats
// returns all available data formats, native and auto-convertible.
string[] dataFormats = dataObject.GetFormats();
// Get the number of data formats present in the data object, including both
// auto-convertible and native data formats.
int numberOfDataFormats = dataFormats.Length;
// To enumerate the resulting array of data formats, and take some action when
// a particular data format is found, use a code structure similar to the following.
foreach (string dataFormat in dataFormats)
{
if (dataFormat == DataFormats.Text)
{
// Take some action if/when data in the Text data format is found.
break;
}
else if(dataFormat == DataFormats.StringFormat)
{
// Take some action if/when data in the string data format is found.
break;
}
}
如需查詢資料物件之可用資料格式的其他範例程式碼,請參閱 HOW TO:列出資料物件中的資料格式。如需查詢資料物件是否有特定資料格式的範例,請參閱 HOW TO:判斷資料格式是否出現在資料物件中。
從資料物件擷取資料
從資料物件擷取特定格式的資料,只需要呼叫其中一個 GetData 方法並指定所要的資料格式即可辦到。有一個 GetDataPresent 方法可以用來檢查是否有特定的資料格式。GetData 會以 Object 傳回資料。視資料格式而定,這個物件可能會轉型為特定型別的容器 (Container)。
下列範例程式碼會先使用 GetDataPresent(String) 多載檢查指定的資料格式 (原生格式或自動轉換的格式) 是否可用。如果指定的資料格式可用,則這個範例會使用 GetData(String) 方法擷取資料。
DataObject dataObject = new DataObject("Some string data to store...");
string desiredFormat = DataFormats.UnicodeText;
byte[] data = null;
// Use the GetDataPresent method to check for the presence of a desired data format.
// This particular overload of GetDataPresent looks for both native and auto-convertible
// data formats.
if (dataObject.GetDataPresent(desiredFormat))
{
// If the desired data format is present, use one of the GetData methods to retrieve the
// data from the data object.
data = dataObject.GetData(desiredFormat) as byte[];
}
如需從資料物件擷取資料的其他範例程式碼,請參閱 HOW TO:擷取特定資料格式的資料。
從資料物件移除資料
資料無法從資料物件直接移除。若要從資料物件有效移除資料,請遵循下列建議步驟:
建立新的資料庫件,這個資料物件將只存放您要保留的資料。
將所要的資料從舊資料物件「複製」到新資料物件。若要複製資料,請使用其中一個 GetData 方法來擷取包含未經處理資料 (Raw Data) 的 Object,然後使用其中一個 SetData 方法將資料加入至新的資料物件。
以新的資料物件取代舊的資料物件。
注意事項: |
---|
SetData 方法只會將資料加入至資料物件,並不會取代資料,即使資料和資料格式與先前的資料和資料格式完全相同也一樣。如果針對同樣的資料和資料格式呼叫兩次 SetData,則資料物件中會出現兩份資料-資料格式。 |