Data binding 是否可以从WPF中的目标控件中手动更新绑定源

Data binding 是否可以从WPF中的目标控件中手动更新绑定源,data-binding,binding,dependency-properties,Data Binding,Binding,Dependency Properties,我有一个场景,我将提供一个简单的例子来帮助说明 假设我正在编写一个自定义的类似复选框的控件,它能够在特定事件触发时被选中。事件可以是任何事件,例如MouseEnter,或者甚至是其他一些非UI事件,例如当网络连接断开时。关键是,在某个时候,我需要手动设置绑定源上的值 我的假设是,这种类型的功能必须是可能的,以便像TextBox这样的控件工作,因为它们的操作方式允许文本属性根据键盘键入的内容更新为值,但不清除文本属性上存在的任何绑定。因此,我试图找到实现这一目标的基本方法 尝试#1 如下所示设置绑

我有一个场景,我将提供一个简单的例子来帮助说明

假设我正在编写一个自定义的类似复选框的控件,它能够在特定事件触发时被选中。事件可以是任何事件,例如MouseEnter,或者甚至是其他一些非UI事件,例如当网络连接断开时。关键是,在某个时候,我需要手动设置绑定源上的值

我的假设是,这种类型的功能必须是可能的,以便像TextBox这样的控件工作,因为它们的操作方式允许文本属性根据键盘键入的内容更新为值,但不清除文本属性上存在的任何绑定。因此,我试图找到实现这一目标的基本方法

尝试#1 如下所示设置绑定的目标属性(例如IsChecked)将导致绑定被清除。因此,此选项将不起作用(更正!请参见下文)

或者:

this.SetValue(CheckBox.IsCheckedProperty, true);
this.SetValue(CheckBox.IsCheckedProperty, true);
尝试#2 BindingBase类有一个名为ProvideValue的属性,如“返回一个应在应用此绑定和扩展的属性上设置的对象”中所述。这听起来很有希望,所以我尝试用下面所示的两种方法实现我自己的

实施A:

public class CheckProvider : IServiceProvider
{
    public object Value { get; set; }

    public object GetService(Type serviceType)
    {
        return Value;
    }
}
实施B:

public class CheckProvider : IServiceProvider
{
    public object Value { get; set; }

    public object GetService(Type serviceType)
    {
        return new ObjectProvider() { TargetObject = new TempDependencyObject() { IsSelected = Value }, TargetProperty = TempDependencyObject.IsSelectedProperty };
    }

    public class TempDependencyObject : DependencyObject
    {
        public object IsSelected
        {
            get { return (object)GetValue(IsSelectedProperty); }
            set { SetValue(IsSelectedProperty, value); }
        }

        public static readonly DependencyProperty IsSelectedProperty =
            DependencyProperty.Register("IsSelected", typeof(object), typeof(TempDependencyObject));
    }

    public class ObjectProvider : System.Windows.Markup.IProvideValueTarget
    {

        public object TargetObject { get; set; }

        public object TargetProperty { get; set; }
    }
}
下面是我如何尝试使用这些类手动更新绑定源代码

myControl.DataContext = obj;
myBinding.ProvideValue(new CheckProvider() { Value = true });

到目前为止,我运气不好,所以如果有人能提供一些建议,我将不胜感激。

你说了几件事

文本框工作,因为他们可以操作 以允许文本属性的方式 根据什么更新为值 键盘正在打字,但没有键盘 清除存在于上的任何绑定 文本属性

这是通过
文本框
更新资源触发器
相关的方式实现的。它默认设置为
LostFocus
。一旦发生
LostFocus
,实际值将被推送到绑定到控件的对象。如果将其设置为
PropertyChanged
,则它将在每个按键笔划后发生

要获得所需的行为,可以在XAML中将
UpdatesourceTrigger
属性设置为
Explicit

<TextBox Name="MyTextBox"
         Text="{Binding Path=FirstName, UpdateSourceTrigger=Explicit}" />
这将与您在发生某个随机事件或其他一系列事件时更新源的需要相结合

如果您试图设置控件外部的可绑定属性的值,并且希望绑定到该属性的属性不会更改;这是不可能开箱即用的。您需要派生自己的控件并在内部对其进行管理,从而公开一个
dependencProperty
,该属性可以采用您想要更新的类型。如果进入VS并键入
propdp
,则会有一个
dependencProperty
的代码段

你会得到像

    public List<byte> Text
    {
        get { return (List<byte>)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(List<byte>), typeof(RichTextBoxExtended), new UIPropertyMetadata());
公共列表文本
{
获取{return(List)GetValue(TextProperty);}
set{SetValue(TextProperty,value);}
}
//使用DependencyProperty作为文本的备份存储。这将启用动画、样式、绑定等。。。
公共静态只读DependencyProperty TextProperty=
Register(“Text”、typeof(List)、typeof(RichTextBoxExtended)、new-UIPropertyMetadata());

Text
是此自定义类型上的一个可绑定属性,它派生自
RichTextBox
。因此,如果有人拥有这种类型的实例,他们可以调用属性本身来设置和更改值。执行此操作时,将通知所有使用此属性并可选绑定到此属性的对象。

有几件事,您声明

文本框工作,因为他们可以操作 以允许文本属性的方式 根据什么更新为值 键盘正在打字,但没有键盘 清除存在于上的任何绑定 文本属性

这是通过
文本框
更新资源触发器
相关的方式实现的。它默认设置为
LostFocus
。一旦发生
LostFocus
,实际值将被推送到绑定到控件的对象。如果将其设置为
PropertyChanged
,则它将在每个按键笔划后发生

要获得所需的行为,可以在XAML中将
UpdatesourceTrigger
属性设置为
Explicit

<TextBox Name="MyTextBox"
         Text="{Binding Path=FirstName, UpdateSourceTrigger=Explicit}" />
这将与您在发生某个随机事件或其他一系列事件时更新源的需要相结合

如果您试图设置控件外部的可绑定属性的值,并且希望绑定到该属性的属性不会更改;这是不可能开箱即用的。您需要派生自己的控件并在内部对其进行管理,从而公开一个
dependencProperty
,该属性可以采用您想要更新的类型。如果进入VS并键入
propdp
,则会有一个
dependencProperty
的代码段

你会得到像

    public List<byte> Text
    {
        get { return (List<byte>)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(List<byte>), typeof(RichTextBoxExtended), new UIPropertyMetadata());
公共列表文本
{
获取{return(List)GetValue(TextProperty);}
set{SetValue(TextProperty,value);}
}
//使用DependencyProperty作为文本的备份存储。这将启用动画、样式、绑定等。。。
公共静态只读DependencyProperty TextProperty=
Register(“Text”、typeof(List)、typeof(RichTextBoxExtended)、new-UIPropertyMetadata());

Text
是此自定义类型上的一个可绑定属性,它派生自
RichTextBox
。因此,如果有人拥有这种类型的实例,他们可以调用属性本身来设置和更改值。执行此操作时,将通知所有使用此属性并可选绑定到此属性的对象。

我的问题的简短答案是“是!”!看完之后
this.SetValue(CheckBox.IsCheckedProperty, true);