|
//---------------------------------------------------------------------------
//
// File: XamlClipboardData.cs
//
// Description:
// A base class which can copy an array of UIElement to the IDataObject as Xaml format.
// It also can retrieve the Xaml data from the IDataObject and create a UIElement array.
//
// Features:
//
// History:
// 11/17/2004 waynezen: Created
//
// Copyright (C) 2001 by Microsoft Corporation. All rights reserved.
//
//---------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Security;
using System.Text;
using System.Diagnostics;
using MS.Internal; //security helper from PresentationCore
namespace MS.Internal.Ink
{
internal class XamlClipboardData : ElementsClipboardData
{
//-------------------------------------------------------------------------------
//
// Constructors
//
//-------------------------------------------------------------------------------
#region Constructors
// The default constructor
internal XamlClipboardData() { }
// The constructor with UIElement[] as an argument
internal XamlClipboardData(UIElement[] elements) : base (elements)
{
}
// Checks if the data can be pasted.
internal override bool CanPaste(IDataObject dataObject)
{
// Check if we have Xaml data
bool hasXamlData = false;
try
{
hasXamlData = dataObject.GetDataPresent(DataFormats.Xaml, false);
}
catch ( SecurityException )
{
// If we are under the partial trust, the Xaml format will fail when it needs to be registered.
// In this case, we should just disable the Paste Xaml format content.
hasXamlData = false;
}
return hasXamlData;
}
#endregion Constructors
//-------------------------------------------------------------------------------
//
// Protected Methods
//
//-------------------------------------------------------------------------------
#region Protected Methods
// Check if we have data to be copied
protected override bool CanCopy()
{
return Elements != null && Elements.Count != 0;
}
// Convert the elements to the Xaml and copy the Xaml to the IDataObject
/// <summary>
///
/// </summary>
/// <param name="dataObject"></param>
///<SecurityNote>
/// Critical: Calls critical method
/// SecurityHelper.ExtractAppDomainPermissionSetMinusSiteOfOrigin
///
/// We call this to ensure that the appdomain permission set is on the clipboard.
/// The Clipboard methods use this information to ensure that apps can not paste data
/// that was copied in low trust to application to a high trust application
///</SecurityNote>
[SecurityCritical]
protected override void DoCopy(IDataObject dataObject)
{
// Serialize the selected elements and add it to the data object.
StringBuilder xmlData = new StringBuilder();
foreach ( UIElement element in Elements )
{
string xml;
xml = XamlWriter.Save(element);
xmlData.Append(xml);
}
// Set the data object as XML format.
dataObject.SetData(DataFormats.Xaml, xmlData.ToString());
//
// we need to copy the permission set on the clipboard for
// the Clipboard class methods. See security note for details.
//
PermissionSet permSet = SecurityHelper.ExtractAppDomainPermissionSetMinusSiteOfOrigin();
string setString = permSet.ToString();
Debug.Assert(setString.Length > 0);
dataObject.SetData(DataFormats.ApplicationTrust, setString);
}
// Retrieves the Xaml from the IDataObject and instantiate the elements based on the Xaml
protected override void DoPaste(IDataObject dataObject)
{
ElementList = new List<UIElement>();
// Get the XML data from the data object.
string xml = dataObject.GetData(DataFormats.Xaml) as string;
if ( !String.IsNullOrEmpty(xml) )
{
bool useRestrictiveXamlReader = !Clipboard.UseLegacyDangerousClipboardDeserializationMode();
UIElement element = XamlReader.Load(new System.Xml.XmlTextReader(new System.IO.StringReader(xml)), useRestrictiveXamlReader) as UIElement;
if (element != null)
{
ElementList.Add(element);
}
}
}
#endregion Protected Methods
}
}
|