Silverlight 5–Markup Extensions

本文介绍了 Silverlight 5 中使用的四种自定义标记扩展:StaticExtension、StandardTwoWayBindingExtension、InvokeExtension 和 ResxExtension。这些扩展可以增强 XAML 的功能,使开发者能够更加灵活地处理 UI 绑定和资源调用。

refer:

http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2011/04/26/silverlight-5-beta-rough-notes-markup-extensions.aspx

http://www.wintellect.com/CS/blogs/jprosise/archive/2011/04/15/using-custom-markup-extensions-in-silverlight-5.aspx

 

1. StaticExtension

public class StaticExtension : MarkupExtension
{
  public string TypeName { get; set; }
  public string PropertyName { get; set; }

  public override object ProvideValue(IServiceProvider serviceProvider)
  {
    object returnValue = null;

    // no checking of any return values at all here.
    var t = Type.GetType(this.TypeName);

    var p = t.GetProperty(this.PropertyName,
      BindingFlags.Static | BindingFlags.Public);

    var v = p.GetValue(null, null);

    // NB: there's more to do here no doubt than just try for IConvertible on
    // a simple property accessor, this is just a sketch.
    if (v is IConvertible)
    {
      IProvideValueTarget ipvt =
        serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;

      if (ipvt != null)
      {
        PropertyInfo pi = (PropertyInfo)ipvt.TargetProperty;

        returnValue = Convert.ChangeType(v, pi.PropertyType, null);
      }
    }
    else
    {
      returnValue = v;
    }
    return (returnValue);
  }
}


Usage 1:

<TextBlock Text="{local:Static TypeName=System.DateTime,PropertyName=Now}" />

Usage 2:

<Grid x:Name="LayoutRoot">
  <Grid.Resources>
    <sys:String
      x:Key="type">System.Windows.Application,System.Windows, Version=5.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e</sys:String>
  </Grid.Resources>
  <TextBlock
    DataContext="{local:Static TypeName={StaticResource type},PropertyName=Current}"
    Text="{Binding InstallState}" />
</Grid>

2. StandardTwoWayBindingExtension


public class StandardTwoWayBindingExtension : Binding
{
  public StandardTwoWayBindingExtension()
  {
    this.ValidatesOnNotifyDataErrors = true;
    this.NotifyOnValidationError = true;
    this.Mode = BindingMode.TwoWay;     
  }
}


Usage:

<Grid x:Name="LayoutRoot">
  <Grid.DataContext>
    <local:DataObject />
  </Grid.DataContext>
  <TextBox Text="{local:StandardTwoWayBinding Path=SomeProperty}" />
</Grid>

3. InvokeExtension


public class InvokeExtension : MarkupExtension
{
  public string MethodName { get; set; }
  public object Source { get; set; }

  public override object ProvideValue(IServiceProvider serviceProvider)
  {
    Delegate returnValue = null;

    Type sourceType = this.Source.GetType();

    MethodInfo methodInfo = sourceType.GetMethod(this.MethodName,
      BindingFlags.Public | BindingFlags.Instance);

    IProvideValueTarget ipvt =
      serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;

    if (ipvt != null)
    {
      EventInfo targetProperty = ipvt.TargetProperty as EventInfo;

      if (targetProperty != null)
      {
        // This is where we fall over if the types of the event and the
        // handler don't match. We could check IsAssignableFrom and do
        // something other than throw.
        returnValue = Delegate.CreateDelegate(
          targetProperty.EventHandlerType, this.Source, methodInfo);
      }
    }
    return (returnValue);
  }
}


Usage:

<Grid
  x:Name="LayoutRoot">
  <Grid.Resources>
    <local:ViewModel x:Key="foo"/>
  </Grid.Resources>
  <Button
    Click="{local:Invoke MethodName=SomeMethod,Source={StaticResource foo}}" />
</Grid>

Or:

<Grid
  x:Name="LayoutRoot">
  <Grid.DataContext>
    <local:ViewModel />
  </Grid.DataContext>
  <Button
    Click="{local:Invoke MethodName=SomeMethod,Source={Binding}}" />
</Grid>

 

4.ResxExtension


public class ResxExtension : MarkupExtension

{

public string ResxType { get; set; }

public string ResxKey { get; set; }

public object Default { get; set; }

public override object ProvideValue(IServiceProvider serviceProvider)

{

if (!String.IsNullOrEmpty(ResxType) && !String.IsNullOrEmpty(ResxKey))

{

try

{

// Create a strongly typed resource manager instance

object resman = Activator.CreateInstance(Type.GetType(ResxType));

// Get the value of the specified property

PropertyInfo pi = resman.GetType().GetProperty(ResxKey);

return pi.GetValue(resman, null);

}

catch (Exception)

{

// Purposely do nothing here to allow the call to fall through

}

}

// If we make it to here, return the default value (if specified) or,

// as a last resort, the key name

if (Default != null)

return Default;

else

return ResxKey;

}

}



转载于:https://www.cnblogs.com/Ruiyi/archive/2011/12/24/2300353.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值