简体   繁体   English

我应该在WPF中使用自定义控件声明绑定选项

[英]Which page should I declare Binding Option with Custom control in WPF

I'm new to make custom control in wpf. 我是新来在wpf中进行自定义控件。
I quite don't understand binding technique with custom control. 我完全不了解自定义控件的绑定技术。
Let me show you my exercise. 让我告诉你我的运动。

I declare my custom control in cs file 我在CS文件中声明我的自定义控件

public class CustomControl1 : Control
{
    static CustomControl1()
    {
        DefaultStyleKeyProperty.OverrideMetadata
            (typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1))
            );
    }

    // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TextaaProperty =
        DependencyProperty.Register(
            "Textaa", 
            typeof(string), typeof(CustomControl1),
            new PropertyMetadata(null));

    public string Textaa
    {
        get { return (string)GetValue(TextaaProperty); }
        set { SetValue(TextaaProperty, value); }
    }
 }

and in Generic.xaml, I declared Template Style for my custom control in Generic.xaml. 在Generic.xaml中,我为Generic.xaml中的自定义控件声明了模板样式。

<Style TargetType="{x:Type local:CustomControl1}">
    <Setter Property="Background" Value="DimGray"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CustomControl1}">
                <TextBox Background="{TemplateBinding Background}" 
                           Text="{Binding Textaa, 
                                 RelativeSource={RelativeSource TemplatedParent}}">
                </TextBox>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

To Text my control, I made My Custom class for Data object that just have name property and just be inherited from INPC 为了给控件添加文本,我为Data对象创建了My Custom类,该类仅具有name属性,并且仅继承自INPC

    public MainWindow()
    {
        InitializeComponent();
        DataContext = new DataObject() { name = "Jeong Yo Han" };
    }

    public class DataObject : INotifyPropertyChanged
    {
        private string _name;
        public string name
        {
            get { return _name; }
            set {
                _name = value;
                onPropertyChanged("name");
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        public void onPropertyChanged(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }  

In my MainWindow Page, I declared my custom control Tag 在我的MainWindow页面中,我声明了自定义控件标签

<Grid>
    <cc:CustomControl1 Background="Red" 
                       Textaa="{Binding name ,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
    </cc:CustomControl1>
</Grid>

I tried to test that does templatedParent in Template Style works for two-way binding. 我尝试测试“模板样式”中的templatedParent是否可以双向绑定。 ( see a RelativeSource= { Rela ... TemplatedParent } ). (请参见RelativeSource = {Rela ... TemplatedParent})。

and I run my program to see when I get hit name setter property in DataObject class. 然后运行程序以查看何时在DataObject类中获得命中名称设置器属性。 even I add UpdateSourceTrigger=PropertyChanged, but It doesn't work well when I change text in my TextBox. 即使我添加了UpdateSourceTrigger = PropertyChanged,但是当我在TextBox中更改文本时,它也无法正常工作。 It works when I lost focus on it, Even I typed UpdateSourceTrigger=PropertyChanged. 即使我键入UpdateSourceTrigger = PropertyChanged,它也会在我失去关注时起作用。

So I Changed my source Like following source. 所以我改变了我的来源像下面的来源。

<!-- in Generic.xaml (Template style) -->
<TextBox Background="{TemplateBinding Background}" 
                           Text="{Binding Textaa, 
                           UpdateSourceTrigger=PropertyChanged,
                                 RelativeSource={RelativeSource TemplatedParent}}">
</TextBox>
<!--- in MainWindow.xaml--->
<cc:CustomControl1 Background="Red" 
                       Textaa="{Binding name ,Mode=TwoWay}" >
 </cc:CustomControl1>

this works well, as I expected. 如我所料,这运作良好。
and following is not working, Not I expected. 和以下不起作用,不是我所期望的。

<!-- in Generic.xaml (Template style) -->
<TextBox Background="{TemplateBinding Background}" 
                           Text="{Binding Textaa, 
                           UpdateSourceTrigger=PropertyChanged, Mode=TwoWay,
                                 RelativeSource={RelativeSource TemplatedParent}}">
</TextBox>
<!--- in MainWindow.xaml--->
<cc:CustomControl1 Background="Red" 
                       Textaa="{Binding name}" >
 </cc:CustomControl1>

But I'm Confusing that why I should put UpdateSourceTrigger Option to StyleTemplate and Mode= TwoWayBinding Option to directly Textaa dependency property of customcontrol tag. 但是我感到困惑的是,为什么我应该将UpdateSourceTrigger Option放到StyleTemplate上,而将Mode = TwoWayBinding Option放到customcontrol标签的Textaa依赖属性上。

I need an explanation. 我需要一个解释。 Thank you for reading. 感谢您的阅读。

for helping your understand I added my reop for my source, below. 为了帮助您理解,我在下面添加了我的资料来源。

click here to see entire source 单击此处查看全部源

The default behavior for updating the source property of a Binding of the Text property of a TextBox is LostFocus . 更新TextBox的Text属性的Binding的source属性的默认行为是LostFocus

See the Remarks on the TextBox.Text Property page: 请参见TextBox.Text属性页上的备注:

When used in data-binding scenarios, this property uses the default update behavior of UpdateSourceTrigger.LostFocus. 在数据绑定方案中使用时,此属性使用UpdateSourceTrigger.LostFocus的默认更新行为。

You do however not need to set Mode=TwoWay , because that is already the default. 但是,您无需设置Mode=TwoWay ,因为这已经是默认设置。 So the TextBox declaration should look like this: 因此,TextBox声明应如下所示:

<TextBox Background="{TemplateBinding Background}" 
         Text="{Binding Textaa,
                UpdateSourceTrigger=PropertyChanged,
                RelativeSource={RelativeSource TemplatedParent}}" />

It is not necessary to set UpdateSourceTrigger=PropertyChanged on the Binding of your Textaa property, because (in contrast to TextBlock.Text ), the default behaviour of your custom dependency property is already PropertyChanged . 不必在Textaa属性的Binding上设置UpdateSourceTrigger=PropertyChanged ,因为(与TextBlock.Text相反),自定义依赖项属性的默认行为已经是PropertyChanged

You may also register your property in a way that makes it bind two-way by default, so that you would not have to set Mode=TwoWay on the Textaa Binding: 您还可以通过默认方式双向绑定来注册属性,这样就不必在Textaa Binding上设置Mode=TwoWay

public static readonly DependencyProperty TextaaProperty =
    DependencyProperty.Register(
        nameof(Textaa), typeof(string), typeof(CustomControl1),
        new FrameworkPropertyMetadata(
            null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

Now you can bind the Textaa property like this: 现在,您可以像这样绑定Textaa属性:

<cc:CustomControl1 Textaa="{Binding name}" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM