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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:21:37  来源:igfitidea点击:

How can I bind inside this ControlTemplate?

wpfxamllistviewbindinguwp

提问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:

有问题的最小项目:

Project

项目

回答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 控件是DependencyObjectsDependencyProperties因此常用:

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:

您也可以使用DataTemplateItemContainerStyle这样的特性:

<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>