File: System\Windows\Input\Command\CommandValueSerializer.cs
Web Access
Project: src\src\Microsoft.DotNet.Wpf\src\PresentationFramework\PresentationFramework.csproj (PresentationFramework)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
//
//  Contents:  ValueSerializer for the ICommand interface
//
 
namespace System.Windows.Input
{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Markup;
    using System.Windows.Documents; // EditingCommands
    using System.Reflection;
 
    internal class CommandValueSerializer : ValueSerializer 
    {
        public override bool CanConvertToString(object value, IValueSerializerContext context)
        {
            if (context == null || context.GetValueSerializerFor(typeof(Type)) == null)
                return false;
 
            // Can only convert routed commands
            RoutedCommand command = value as RoutedCommand;
 
            if (command == null || command.OwnerType == null)
            {
                return false;
            }
            
            if (CommandConverter.IsKnownType(command.OwnerType))
            {
                return true;
            }
            else
            {
                string localName = $"{command.Name}Command";
                Type ownerType = command.OwnerType;
                string typeName = ownerType.Name;
 
                // Get them from Properties
                PropertyInfo propertyInfo = ownerType.GetProperty(localName, BindingFlags.Public | BindingFlags.Static);
                if (propertyInfo != null)
                    return true;
 
                // Get them from Fields (ScrollViewer.PageDownCommand is a static readonly field
                FieldInfo fieldInfo = ownerType.GetField(localName, BindingFlags.Static | BindingFlags.Public);
                if (fieldInfo != null)
                    return true;
            }
 
            return false; 
        }
 
        public override bool CanConvertFromString(string value, IValueSerializerContext context)
        {
            return true;
        }
 
        public override string ConvertToString(object value, IValueSerializerContext context)
        {
            if (value != null)
            {
                RoutedCommand command = value as RoutedCommand;
                if (null != command && null != command.OwnerType)
                {
                    // Known Commands, so write shorter version
                    if (CommandConverter.IsKnownType(command.OwnerType))
                    {
                        return command.Name;
                    }
                    else
                    {
                        ValueSerializer typeSerializer = null;
 
                        if (context == null)
                        {
                            throw new InvalidOperationException(SR.Format(SR.ValueSerializerContextUnavailable, this.GetType().Name ));
                        }
 
                        // Get the ValueSerializer for the System.Type type
                        typeSerializer = context.GetValueSerializerFor(typeof(Type));
                        if (typeSerializer == null)
                        {
                            throw new InvalidOperationException(SR.Format(SR.TypeValueSerializerUnavailable, this.GetType().Name ));
                        }
 
                        return $"{typeSerializer.ConvertToString(command.OwnerType, context)}.{command.Name}Command";
                    }
                }
            }
            else
                return string.Empty;
            
            throw GetConvertToException(value, typeof(string));
        }
 
        public override IEnumerable<Type> TypeReferences(object value, IValueSerializerContext context)
        {
            if (value != null)
            {
                RoutedCommand command = value as RoutedCommand;
                if (command != null)
                {
                    if (command.OwnerType != null && !CommandConverter.IsKnownType(command.OwnerType))
                    {
                        return new Type[] { command.OwnerType };
                    }
                }
            }
            return base.TypeReferences(value, context);
        }
 
        public override object ConvertFromString(string value, IValueSerializerContext context)
        {
            if (value != null)
            {
                if (value.Length != 0)
                {
                    Type declaringType = null;
                    String commandName;
 
                    // Check for "ns:Class.Command" syntax.
                    
                    int dotIndex = value.IndexOf('.');
                    if (dotIndex >= 0)
                    {
                        // We have "ns:Class.Command" syntax.
 
                        // Find the type name in the form of "ns:Class".
                        string typeName = value.Substring(0, dotIndex);
 
                        if (context == null)
                        {
                            throw new InvalidOperationException(SR.Format(SR.ValueSerializerContextUnavailable, this.GetType().Name ));
                        }
 
                        // Get the ValueSerializer for the System.Type type
                        ValueSerializer typeSerializer = context.GetValueSerializerFor(typeof(Type));
                        if (typeSerializer == null)
                        {
                            throw new InvalidOperationException(SR.Format(SR.TypeValueSerializerUnavailable, this.GetType().Name ));
                        }
 
 
                        // Use the TypeValueSerializer to parse the "ns:Class" into a System.Type.
                        declaringType = typeSerializer.ConvertFromString(typeName, context) as Type;
 
                        // Strip out the "Command" part of "ns:Class.Command".
                        commandName = value.Substring(dotIndex + 1).Trim();
                    }
                    else
                    {
                        // Assume the known commands
                        commandName = value.Trim();
                    }
 
                    // Find the command given the declaring type & name (this is shared with CommandConverter)
                    ICommand command = CommandConverter.ConvertFromHelper( declaringType, commandName );
 
                    if (command != null)
                    {
                        return command;
                    }
                }
                else
                {
                    return null; // String.Empty <==> null , (for roundtrip cases where Command property values are null)
                }
            }
 
            return base.ConvertFromString(value, context);
        }
    }
}