长话短说,是否有一种编程方式(代码背后)来创建现有绑定的克隆?
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属性的验证。