我有一段时间试图模板绑定矩形的StrokeThickness。
我的目标是允许我的自定义控件的用户设置名为SelectedBorderThickness的属性,实际上,它将设置矩形的StrokeThickness。
我以为我理解模板,但我想我真的没有。
如果我这样做:
<Rectangle x:Name="myRect" Height="100" Width="100" Stroke="Black" SelectedBorderThickness="5" />
有人可以告诉我如何编写Style元素以使其工作吗?
答案 0 :(得分:1)
您应该为问题添加更多详细信息,人们将能够更轻松地为您提供帮助。我想我已经想出了你想要的东西。
您正在寻找一个自定义模板化的silverlight控件,其中包含一组元素,包括模板中的矩形。您希望用户能够使用控件本身的属性在控件内设置该矩形的厚度。从你上面提到的内容来看,我不知道你在代码中写了多少 - 所以我只会发布一个几乎完整的例子来说明你的目标。
首先,我在visual studio中创建了一个模板化自定义控件,并添加了我们希望用户能够设置的新依赖属性:
public class TestControl : Control
{
static public DependencyProperty SBTProperty { get; set; }
static TestControl()
{
SBTProperty = DependencyProperty.Register("SelectedBorderThickness", typeof(double), typeof(TestControl),null);
}
public TestControl()
{
this.DefaultStyleKey = typeof(TestControl);
}
public double SelectedBorderThickness
{
get { return (double)GetValue(SBTProperty); }
set { SetValue(SBTProperty, value); }
}
}
然后我在Generic.xaml中设置了模板(对于我的例子,我控制的唯一东西是矩形,因为我不知道你想要什么):
<Style TargetType="local:TestControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:TestControl">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Rectangle Fill="Bisque" Stroke="Black" StrokeThickness="{TemplateBinding SelectedBorderThickness}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
现在我已经准备好在我的应用程序的其他部分使用xaml了。在我的例子中,我把一个放在我的MainPage的中心:
<local:TestControl SelectedBorderThickness="75"></local:TestControl>
编辑: 在阅读下面的代码后,我现在看到问题所在。您正在尝试进行模板绑定,但是您拥有它的方式将尝试绑定到当前模板,该模板是listboxitem的模板,而不是您的自定义列表框。在这种情况下你真正想要的是用FindAncestor做一个RelativeBinding来将树跳到自定义列表框的模板,但是MS还没有在Silverlight中实现那种绑定(即使它在WPF中很常见)。幸运的是,在您的特定情况下,我们可以通过TemplatedParent绑定中的路径来捕获正确的对象,而无需编写一堆杂乱的代码隐藏来模拟祖先绑定:
StrokeThickness="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content.Parent.SelectedBorderThickness}"
将其转移到上面发布的模板的Rectangle中,它应该可以工作 - 它将访问ListBoxItem的内容(这是你正在显示的内容),然后访问那些对象Parent(这将是你的自定义列表框) 。从那里我们只是打了我们之前设置的房产。
如果您想要更清晰的解决方案,请加入我们的合唱团,要求MS在Silverlight中实现祖先绑定。
答案 1 :(得分:1)
答案 2 :(得分:0)
这是问题部分,当我尝试为从ListBox派生的自定义控件设置ItemContainerStyle样式时:
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid Background="{TemplateBinding Background}">
<!-- VSM stuff removed for clarity -->
<ContentPresenter
x:Name="contentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"/>
<Rectangle x:Name="FocusVisualElement"
Stroke="Goldenrod"
StrokeThickness="{TemplateBinding SelectedBorderThickness}"
Visibility="Collapsed"
RadiusX="1"
RadiusY="1" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
问题是当我在Rectangle上设置StrokeThickness = {TemplateBinding SelectedBorderThickness}然后尝试在测试应用程序中使用该控件时,我得到一个ParserError:
Message: Unknown attribute StrokeThickness on element Rectangle
如果我将StrokeThickness硬编码为3(或其他),它解析得很好,我可以查看测试应用程序。
最后,我真正想做的就是创建一个显示在Intellisense中的属性,以便我的自定义控件的最终用户可以更改颜色和边框的厚度,半径等。突出显示在动态绑定的自定义ListBox中的悬停和选定的ListBoxItem。这不应该是这种困难。
答案 3 :(得分:0)
这些评论太受限制了。我不是想回答我自己的问题(我希望我能)。
David,你的代码在静态添加ListBoxItems时工作正常。动态添加它们时,厚度不会改变。为了测试这个,我在MainPage中添加了一个新的TestControl:
<StackPanel>
<local:TestControl SelectedBorderThickness="9" x:Name="h1n1">
<TextBlock Text="Honk1"></TextBlock>
<TextBlock Text="Honk2"/>
</local:TestControl>
<local:TestControl x:Name="SwineFlu" SelectedBorderThickness="20" />
</StackPanel>
在代码隐藏中我添加了:
ObservableCollection<string> test = new ObservableCollection<string>();
test.Add("Hi David");
test.Add("Hello World");
SwineFlu.ItemsSource = test;