我创建了一个继承自 AvalonEdit 的自定义 TextEditor
控件。我这样做是为了方便使用此编辑器控件使用 MVVM 和 Caliburn Micro。 [为显示目的而缩减] MvvTextEditor
类是
public class MvvmTextEditor : TextEditor, INotifyPropertyChanged
{
public MvvmTextEditor()
{
TextArea.SelectionChanged += TextArea_SelectionChanged;
}
void TextArea_SelectionChanged(object sender, EventArgs e)
{
this.SelectionStart = SelectionStart;
this.SelectionLength = SelectionLength;
}
public static readonly DependencyProperty SelectionLengthProperty =
DependencyProperty.Register("SelectionLength", typeof(int), typeof(MvvmTextEditor),
new PropertyMetadata((obj, args) =>
{
MvvmTextEditor target = (MvvmTextEditor)obj;
target.SelectionLength = (int)args.NewValue;
}));
public new int SelectionLength
{
get { return base.SelectionLength; }
set { SetValue(SelectionLengthProperty, value); }
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged([CallerMemberName] string caller = null)
{
var handler = PropertyChanged;
if (handler != null)
PropertyChanged(this, new PropertyChangedEventArgs(caller));
}
}
现在,在包含此控件的 View 中,我有以下 XAML:
<Controls:MvvmTextEditor
Caliburn:Message.Attach="[Event TextChanged] = [Action DocumentChanged()]"
TextLocation="{Binding TextLocation, Mode=TwoWay}"
SyntaxHighlighting="{Binding HighlightingDefinition}"
SelectionLength="{Binding SelectionLength,
Mode=TwoWay,
NotifyOnSourceUpdated=True,
NotifyOnTargetUpdated=True}"
Document="{Binding Document, Mode=TwoWay}"/>
我的问题是 SelectionLength
(和 SelectionStart
但让我们现在只考虑长度,因为问题是一样的)。如果我用鼠标选择了一些东西,从 View 到我的 View 模型的绑定(bind)效果很好。现在,我已经编写了一个查找和替换实用程序,我想设置 SelectionLength
(在 中有
控制)从后面的代码。在我的 View 模型中,我只是设置 get
和 set
可用TextEditorSelectionLength = 50
,我在 View 模型中实现了它,例如
private int selectionLength;
public int SelectionLength
{
get { return selectionLength; }
set
{
if (selectionLength == value)
return;
selectionLength = value;
Console.WriteLine(String.Format("Selection Length = {0}", selectionLength));
NotifyOfPropertyChange(() => SelectionLength);
}
}
当我设置 SelectionLength = 50
时,DependencyProperty SelectionLengthProperty
不会在 MvvmTextEditor
类中更新,就像 TwoWay
绑定(bind)到我的控件失败,但使用 Snoop 没有任何迹象。我认为这只能通过绑定(bind)来工作,但事实并非如此。
我是否遗漏了一些简单的东西,或者我是否必须在 MvvmTextEditor
类中设置和事件处理程序,该类监听我的 View 模型中的变化并更新 DP 本身 [which提出它自己的问题]?
感谢您的宝贵时间。
最佳答案
这是因为 DependencyProperty
中的 Getter
和 Setter
只是一个 .NET Wrapper。框架将使用 GetValue
和 SetValue
本身。
您可以尝试从 DependencyProperty
访问 PropertyChangedCallback
并在那里设置正确的值。
public int SelectionLength
{
get { return (int)GetValue(SelectionLengthProperty); }
set { SetValue(SelectionLengthProperty, value); }
}
// Using a DependencyProperty as the backing store for SelectionLength. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectionLengthProperty =
DependencyProperty.Register("SelectionLength", typeof(int), typeof(MvvmTextEditor), new PropertyMetadata(0,SelectionLengthPropertyChanged));
private static void SelectionLengthPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var textEditor = obj as MvvmTextEditor;
textEditor.SelectionLength = e.NewValue;
}
关于c# - 使用 MVVM 在 WPF 中绑定(bind)失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23827718/