在运行时绑定时更改UpdateSourceTrigger

时间:2016-11-02 01:30:59

标签: wpf data-binding

长话短说,是否有一种编程方式(代码背后)来创建现有绑定的克隆?

var internalTextBoxRef = RichTextEditor.FindName("mainRTB") as RichTextBox;
var bindingMarkup = MarkupWriter.GetMarkupObjectFor(internalTextBoxRef).Properties.FirstOrDefault(x => x.IsAttached);
var bindingBase = BindingOperations.GetBindingBase(internalTextBoxRef, bindingMarkup.DependencyProperty);
var b = bindingBase as Binding;

// Since you can't modify a binding that's already in use
// we need to clone, delete existing and attach a new modified one.
var newBinding = new Binding(b.Path.Path)
{
    ElementName = b.ElementName,
    UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};

BindingOperations.ClearBinding(internalTextBoxRef, bindingMarkup.DependencyProperty);
BindingOperations.SetBinding(internalTextBoxRef, bindingMarkup.DependencyProperty, newBinding );

以上是我目前正在做的事情。但是,当我执行此操作时,使用此绑定的控件开始执行奇怪的操作,例如在每次按键之后,光标将转到文本框的开头。我发现很难相信简单地更改UpdateSourceTrigger会导致这种情况,所以我的直觉告诉我原始绑定中还有其他东西在新绑定中丢失了。在调试器中看,唯一看起来不同的是' Flags'属性。但是' Flags'属性无法设置,我找不到任何描述如何生成标志的信息。

有人能建议克隆原始绑定的方法吗?

修改1

这是我的xaml绑定:

<wpfRichText:RichTextEditor x:Name="RichTextEditor"
        Grid.Row="3" HorizontalAlignment="Left" Margin="0,0,0,10" 
        IsContextMenuEnabled="True" IsToolBarVisible="True" IsReadOnly="False"
        Background="{DynamicResource {x:Static SystemColors.ControlLightLightBrushKey}}"
        Foreground="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"
        Width="{Binding ActualWidth, ElementName=EmailerLayoutGrid}"
        BorderThickness="1" BorderBrush="{DynamicResource {x:Static SystemColors.MenuBarBrushKey}}"
        Text="{Binding HtmlBodyText, Mode=OneWayToSource}" />

添加UpdateSourceTrigger =&#34; PropertyChanged&#34;到文本绑定没有做任何事情(这就是我尝试上面的恶作剧的原因)。如果您对控件本身的xaml感兴趣,可以找到它here

修改2

所以我已经解决了这个绑定问题,以获得我需要做的事情。不幸的是,我不得不打破MVVM范式来完成它。基本上我需要在用户输入时进行绑定更新以启用按钮,以便他们可以继续他们的工作流程。不幸的是,配置wpfrichtexteditor控件的方式,您必须将焦点更改为另一个控件以使绑定更新。由于此控件也接受选项卡,因此您无法从控件中跳出选项并进行更新。您必须导航到另一个控件。我正在处理的视图的下一个控件是您为了继续工作流而按下的按钮,该按钮在richtext绑定更新之前被禁用。因此,用户必须使用鼠标单击以前的文本框才能继续。这是IMO不可接受的可用性。

所以我最终在后面的代码中执行以下操作以获得所需的行为:

public partial class SomeUserControlView
{
    public SomeUserControlView()
    {
        InitializeComponent();
        CloseViewModelOnUnloaded = false;
        var internalTextBoxRef = RichTextEditor.FindName("mainRTB") as RichTextBox;
        internalTextBoxRef.TextChanged += OnTextChanged;
    }

    private void OnTextChanged(object sender, TextChangedEventArgs textChangedEventArgs)
    {
        var control = sender as RichTextBox;
        var doc = control.Document;

        var text = new TextRange(doc.ContentStart, doc.ContentEnd).Text;

        var viewModel = ViewModel as SomeUserControlViewModel;
        viewModel.HasBodyText = !string.IsNullOrWhiteSpace(text);
    }
}

我的按钮绑定到一个命令,该命令具有检查(其中包括)HasBodyText属性的验证。

0 个答案:

没有答案