问题描述
我在使用 WindowsPhone 8 和 ControlTemplate 时遇到了绑定问题.下面是一个例子:
I have a binding problem with WindowsPhone 8 and a ControlTemplate.Here is an example:
<UserControl.Resources>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentControl x:Name="ContentContainer" Foreground="Red" Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Button>
<Button.Content>
<TextBlock Text="123"/>
</Button.Content>
<Button>
我想在我的 Button.Content 中使用我在 ContentContainer 中定义的前景红色".但没有任何作用...目标是在我的样式中更改 VisualState 中的 ContentContainer 前景.有人可以帮我吗?
I would like to use in my Button.Content the foreground "Red" I defined in the ContentContainer. But nothing works...The goal is to change the ContentContainer foreground in a VisualState in my Style. Can anyone help me?
推荐答案
设法通过行为实现了这一点.这是一个相当复杂的解决方案,但这是我发现的唯一一个工作:
Managed to pull this off with a behavior. It's a pretty complicated solution,but it's the only one i found working :
首先,一些实用的东西:
First, some Util stuff :
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;
}
}
现在,让我们定义一个执行绑定的行为:
Now, let's define a behavior that does the binding :
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
});
};
}
}
此行为的作用是将控件的前景绑定到在指定父级模板中找到的 ContentControl 的前景.这是您使用它的方式(在 xaml 中):
What this behavior does is bind the control's foreground to the foreground of the ContentControl found in the template of the specified parent.This is how you use it (in 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>
这篇关于从 ContentControl 绑定前景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!