wpf 如何在此 ControlTemplate 内绑定?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32182037/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I bind inside this ControlTemplate?
提问by vrwim
I have a ListView, filled with a List<MyListItem>and I need to use a ControlTemplateto be able to change the effects when an item is selected. Now I have the problem that {Binding MyProperty}doesn't work inside of that ControlTemplate. How can I access the properties of MyListIteminside the template?
我有一个ListView, 填充了 aList<MyListItem>并且我需要使用 aControlTemplate才能在选择项目时更改效果。现在我遇到了{Binding MyProperty}在里面不起作用的问题ControlTemplate。如何访问MyListItem模板内部的属性?
My XAML looks like this(simplified):
我的 XAML 看起来像这样(简化):
<ListView
Name="ListView"
Grid.Column="1"
IsSwipeEnabled="False">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected">
<Storyboard>
<ColorAnimation Duration="0" Storyboard.TargetName="myColoredText" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="Orange"/>
</Storyboard>
</VisualState>
<VisualState x:Name="SelectedUnfocused">
<Storyboard>
<ColorAnimation Duration="0" Storyboard.TargetName="myColoredText" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="Red"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!-- Here I have my custom layout, removed for readability -->
<TextBlock
Name="myColoredText"
Foreground="Green"
Text="{Binding MyProperty}"/><!-- This does not work -->
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
Here is the class behind this XAML:
这是此 XAML 背后的类:
public sealed partial class MyPage : Page
{
public MyPage()
{
InitializeComponent();
ListView.ItemsSource = new List<MyListItem>()
{
new MyListItem("Title1", "SubTitle1"),
new MyListItem("Title2", "SubTitle2")
}
}
}
and the MyListItem class:
和 MyListItem 类:
class MyListItem
{
public string MyProperty { get; set; }
public string MyOtherProperty { get; set; }
public MyListItem(string myProperty, string myOtherProperty)
{
MyProperty = myProperty;
MyOtherProperty = myOtherProperty;
}
}
Smallest project with the problem:
有问题的最小项目:
回答by XAMeLi
In the TextBox, use:
在 中TextBox,使用:
Text="{Binding Content.MyProperty,
RelativeSource={RelativeSource TemplatedParent}}"
回答by VMaleev
Wpf supports binding only to properties, not to fields. So, you MyItemClass should be:
Wpf 仅支持绑定到属性,而不支持绑定到字段。所以,你的 MyItemClass 应该是:
public class MyListItem {
public string MyProperty { get; set; }
public string MyOtherProperty { get; set; }
public MyListItem(string myProperty, string myOtherProperty) {
MyProperty = myProperty;
MyOtherProperty = myOtherProperty;
}
}
Hope, it helps
希望能帮助到你
回答by James Wright
You need to use the {TemplateBinding}expression when dealing with custom ControlTemplates. This binds property values to any corresponding properties associated with a control instance.
{TemplateBinding}处理 custom 时需要使用表达式ControlTemplate。这将属性值绑定到与控件实例关联的任何相应属性。
<TextBlock Name="myColoredText"
Foreground="Green"
Text="{TemplateBinding MyProperty}" />
This will bind to directly to the specified instance property in your control. Since WPF/WinRT controls are DependencyObjects, DependencyPropertiesare commonly used:
这将直接绑定到控件中指定的实例属性。由于 WPF/WinRT 控件是DependencyObjects,DependencyProperties因此常用:
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register(
"MyProperty",
typeof(Boolean),
typeof(ListViewItem),
null
);
public bool MyProperty
{
get { return (bool)GetValue(MyPropertyProperty); }
set { SetValue(MyPropertyProperty, value); }
}
Then when declaring a new instance, one would populate this property as is standard in XAML:
然后在声明一个新实例时,将按照 XAML 中的标准填充此属性:
<someNamespace:ListViewItem MyProperty={Binding ViewModelProperty} />
You can read more on the TemplateBinding markup expression at MSDN.
您可以在MSDN上阅读有关 TemplateBinding 标记表达式的更多信息。
回答by Sheridan
A ControlTemplateis typically used to define what a control should look like. It is therefore much easier to put your XAML into a DataTemplateand assign it to the ListView.ItemTemplateproperty instead. You can access all of your custom properties from the DataTemplate:
AControlTemplate通常用于定义控件的外观。因此,将 XAML 放入 aDataTemplate并将其分配给ListView.ItemTemplate属性要容易得多。您可以从以下位置访问所有自定义属性DataTemplate:
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Name="myColoredText" Foreground="Green"
Text="{Binding MyProperty}" /><!-- This will now work -->
</DataTemplate>
</ListView.ItemTemplate>
UPDATE >>>
更新 >>>
You can also use a DataTemplatefrom the ItemContainerStyleproperty like this:
您也可以使用DataTemplate从ItemContainerStyle这样的特性:
<Style x:Key="SomeStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate DataType="{x:Type Your:DataType}">
<TextBlock Name="myColoredText" Foreground="Green"
Text="{Binding MyProperty}" /><!-- This will now work -->
</DataTemplate>
</Setter.Value>
</Setter>
</Style>

