由於您無法使用正常的元素/屬性級語法,因此您可以使用混合行爲來定位CombinedControl
上的Instance
屬性,並將其屬性ExampleProp
設置爲您想要的值。這需要添加對System.Windows.Interactivity的引用,該引用是Blend SDK(隨Visual Studio附帶)的一部分。首先是主要行爲:
using System;
using System.ComponentModel;
using System.Reflection;
using System.Windows;
using System.Windows.Interactivity;
// Sets properties on targeted items via XAML.
public class SetPropertyBehavior : Behavior<FrameworkElement>
{
// Name of the property we want to set on our target.
public static DependencyProperty PropertyNameProperty =
DependencyProperty.Register("PropertyName", typeof(string), typeof(SetPropertyBehavior),
new PropertyMetadata(OnTargetPropertyOrValueChanged));
public string PropertyName
{
get { return (string)GetValue(PropertyNameProperty); }
set { SetValue(PropertyNameProperty, value); }
}
// Value of the property we want to set.
public static DependencyProperty PropertyValueProperty =
DependencyProperty.Register("PropertyValue", typeof(object), typeof(SetPropertyBehavior),
new PropertyMetadata(OnTargetPropertyOrValueChanged));
public object PropertyValue
{
get { return GetValue(PropertyValueProperty); }
set { SetValue(PropertyValueProperty, value); }
}
// Target object that has the property we want to set. If this is null, the behavior's
// associated object will be the target instead.
public static DependencyProperty TargetProperty =
DependencyProperty.Register("Target", typeof(object), typeof(SetPropertyBehavior),
new PropertyMetadata(OnTargetPropertyOrValueChanged));
public object Target
{
get { return GetValue(TargetProperty); }
set { SetValue(TargetProperty, value); }
}
protected override void OnAttached()
{
UpdateTargetProperty();
}
private static void OnTargetPropertyOrValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var behavior = d as SetPropertyBehavior;
if(behavior != null)
behavior.UpdateTargetProperty();
}
private void UpdateTargetProperty()
{
// Ensure we have a property name and target to work with.
if(string.IsNullOrEmpty(this.PropertyName))
return;
var target = this.Target ?? this.AssociatedObject;
if(target == null)
return;
// Make sure our property is actually on our target.
var targetType = target.GetType();
PropertyInfo propInfo = targetType.GetProperty(this.PropertyName,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if(propInfo == null)
return;
// Try to convert the string from the XAML to a value the target property can store.
TypeConverter converter = TypeDescriptor.GetConverter(propInfo.PropertyType);
object propValue = null;
try
{
if(converter.CanConvertFrom(this.PropertyValue.GetType()))
propValue = converter.ConvertFrom(this.PropertyValue);
else
propValue = converter.ConvertFrom(this.PropertyValue.ToString());
}
catch(Exception)
{
// Do whatever is appropriate in your case.
propValue = null;
}
propInfo.SetValue(target, propValue);
}
}
然後取決於它讓你最感設定值ExampleProp
,您將通過XAML添加的行爲。例如,如果您添加的XAML內的行爲爲您CombinedControl
,它可能是這個樣子:
<UserControl x:Class="NameSpaceName.CombinedControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:NameSpaceName"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
x:Name="Root">
<i:Interaction.Behaviors>
<local:SetPropertyBehavior Target="{Binding Instance, ElementName=Root}" PropertyName="ExampleProp" PropertyValue="10"/>
</i:Interaction.Behaviors>
<!-- Rest of control here -->
</UserControl>
如果你想從XAML做任何的母公司在託管您CombinedControl
,你可以像這個(使用基本的WPF Window
作爲例子):
<Window x:Class="NameSpaceName.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:NameSpaceName"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
Title="MainWindow" Height="350" Width="525">
<i:Interaction.Behaviors>
<local:SetPropertyBehavior Target="{Binding Instance, ElementName=myCombinedControl}" PropertyName="ExampleProp" PropertyValue="10"/>
</i:Interaction.Behaviors>
<Grid>
<local:CombinedControl x:Name="myCombinedControl"/>
</Grid>
</Window>
典型的方法是也暴露UserControl中的'ExampleProp'。在UserControl的XAML中,您可以將DerivedControl的ExampleProp綁定到UserControl實例的DerivedControl的ExampleProp。 – Clemens
是的,那對我來說是不幸的。由於MainControl擁有超過100個屬性,並且將它們全部放入CombinedControl中並不是一種方法,所以我的目標是通過對象本身訪問屬性。注意:MainControl來自第三方,所以我沒有它的來源。這就是爲什麼我甚至使用這個派生模型。 – Karolis