我对WindowsPhone 8和ControlTemplate存在绑定问题。 这是一个例子:
<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中定义的前景“Red”。但没有任何作用...... 目标是在我的Style中更改VisualState中的ContentContainer前景。任何人都可以帮助我吗?
答案 0 :(得分:0)
你应该这样做:
<Button Content="123"/>
而不是放置TextBlock。
但是如果你想保留TextBlock,你应该这样做:
<Style TargetType="TextBlock">
<Setter Property="Foreground">
<Setter.Value>
red
</Setter.Value>
</Setter>
</Style>
答案 1 :(得分:0)
通过行为来管理这个问题。这是一个非常复杂的解决方案, 但它是我发现的唯一一个工作:
首先,一些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
});
};
}
}
此行为的作用是将控件的前景绑定到在指定父级的模板中找到的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>