管理與行爲拉這一關。這是一個相當複雜的解決方案, 但它是唯一一個我找到工作:
首先,一些的Util東西:
public static class IEnumerableExt
{
public static T FirstOrDefault<T>(this IEnumerable<T> source)
{
if (source.Count() > 0)
return source.ElementAt(0);
return default(T);
}
}
和...
public static class DependencyObjectExt
{
public static DependencyObject GetChild(this DependencyObject @this, int childIndex)
{
return VisualTreeHelper.GetChild(@this, childIndex);
}
public static IEnumerable<DependencyObject> GetChildren(this DependencyObject @this)
{
for(int i = 0; i < VisualTreeHelper.GetChildrenCount(@this); i++)
{
yield return @this.GetChild(i);
}
}
public static IEnumerable<T> FindChildrenOfType<T>(this DependencyObject @this) where T : DependencyObject
{
foreach(var child in @this.GetChildren())
{
if(child is T)
{
yield return child as T;
}
}
}
public static IEnumerable<T> FindDescendantsOfType<T>(this DependencyObject @this) where T : DependencyObject
{
IEnumerable<T> result = Enumerable.Empty<T>();
foreach(var child in @this.GetChildren())
{
if(child is T)
{
result = result.Concat(child.ToEnumerable().Cast<T>());
}
result = result.Concat(child.FindDescendantsOfType<T>());
}
return result;
}
}
現在,讓我們定義一個行爲綁定:
public class ContentControlForegroundBindingBehavior : Behavior<Control>
{
public static DependencyProperty ParentProperty =
DependencyProperty.Register("Parent", typeof(Control),
typeof(ContentControlForegroundBindingBehavior), new PropertyMetadata(null));
public Control Parent
{
get { return (Control)this.GetValue(ParentProperty); }
set { this.SetValue(ParentProperty, value); }
}
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Loaded += (sender, e) =>
{
if (Parent == null) return;
var control = AssociatedObject as Control;
if (control == null) return;
var contentControl = Parent.FindDescendantsOfType<ContentControl>().FirstOrDefault();
if (contentControl == null) return;
control.SetBinding(Control.ForegroundProperty, new Binding()
{
NotifyOnSourceUpdated = true,
Mode = BindingMode.OneWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
BindsDirectlyToSource = true,
Path = new PropertyPath(Control.ForegroundProperty),
Source = contentControl
});
};
}
}
此行爲的作用是綁定c控制的前景到指定父級的模板中找到的ContentControl的前景。 這是你如何使用它(在xaml中):
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:behaviors=" ---------- Your Behaviors Namespace ---------"
<Button x:Name="SomeName"
Width="125"
Height="30"
Click="OnButtonClick"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="50,54,0,0">
<Button.Content>
<controls:IconText Icon="SomeIcon.png"
Text="SomeText">
<i:Interaction.Behaviors>
<behaviors:ContentControlForegroundBindingBehavior Parent="{Binding ElementName=SomeName}"/>
</i:Interaction.Behaviors>
</controls:IconText>
</Button.Content>
</Button>
這是一個最小的例子。我真正的按鈕內容更復雜。當我用自己的風格定義前景時,我不能在視覺狀態下改變前景 – user3336897
然後你應該發佈你的真實代碼,這樣我們可以理解你的情況 – AymenDaoudi