IsKeyboardFocusWithinプロパティを追跡し、キーボードフォーカスが含まれていない場合にのみターゲット値を更新するヘルパーを作成できます。例では 、あなたは刻々と変化し、特定のソースがあります。これは、Dataプロパティである。この場合
public partial class MainWindow {
public static readonly DependencyProperty DataProperty = DependencyProperty.Register(
"Data", typeof(string), typeof(MainWindow), new PropertyMetadata(default(string), OnDataChanged));
static void OnDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
Debug.WriteLine((string)e.NewValue);
}
public string Data {
get { return (string)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public MainWindow() {
InitializeComponent();
DispatcherTimer dt = new DispatcherTimer();
dt.Interval = TimeSpan.FromMilliseconds(1000);
dt.Tick += Dt_Tick;
dt.Start();
}
void Dt_Tick(object sender, EventArgs e) {
Data = new Random().Next(0, 100).ToString();
}
}
を。今、助けてください。 - 記憶目標値(Helper.TargetProperty
) とに使用される第3 1記憶ソースから実際の値秒(Helper.SourceProperty
) :我々は、3つの特性を有する
public class SynchronizationHelperExtension : MarkupExtension {
public Binding Binding { get; set; }
class Helper {
static int index = 0;
bool locked = false;
public static readonly DependencyProperty HelperProperty = DependencyProperty.RegisterAttached(
"Helper", typeof(Helper), typeof(Helper), new PropertyMetadata(default(Helper)));
public static void SetHelper(DependencyObject element, Helper value) {
element.SetValue(HelperProperty, value);
}
public static Helper GetHelper(DependencyObject element) {
return (Helper)element.GetValue(HelperProperty);
}
public static readonly DependencyProperty FocusProperty = DependencyProperty.RegisterAttached("FocusProperty", typeof(bool), typeof(Helper), new PropertyMetadata(false, (o, args) => GetHelper(o)?.OnFocusPropertyChanged(o, (bool)args.OldValue, (bool)args.NewValue)));
public static readonly DependencyProperty SourceProperty = DependencyProperty.RegisterAttached("SourceProperty", typeof(object), typeof(Helper), new PropertyMetadata(false, (o, args) => GetHelper(o)?.OnSourcePropertyChanged(o, args.OldValue, args.NewValue)));
public static readonly DependencyProperty TargetProperty = DependencyProperty.RegisterAttached("TargetProperty", typeof(object), typeof(Helper), new PropertyMetadata(false, (o, args) => GetHelper(o)?.OnTargetPropertyChanged(o, args.OldValue, args.NewValue)));
void OnTargetPropertyChanged(DependencyObject o, object oldValue, object newValue) {
o.SetValue(SourceProperty, newValue);
}
void OnSourcePropertyChanged(DependencyObject o, object oldValue, object newValue) {
if (locked)
return;
o.SetValue(TargetProperty, newValue);
}
void OnFocusPropertyChanged(DependencyObject o, bool oldValue, bool newValue) {
locked = newValue;
}
}
public override object ProvideValue(IServiceProvider serviceProvider) {
var helper = new Helper();
var ipwt = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
var dObj = ipwt.TargetObject as DependencyObject;
BindingOperations.SetBinding(dObj, Helper.FocusProperty, new Binding() {Path = new PropertyPath(FrameworkElement.IsKeyboardFocusWithinProperty), RelativeSource = RelativeSource.Self});
Binding.Mode = BindingMode.TwoWay;
BindingOperations.SetBinding(dObj, Helper.SourceProperty, Binding);
Helper.SetHelper(dObj, helper);
return new Binding() {Path = new PropertyPath(Helper.TargetProperty), Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.LostFocus, RelativeSource = RelativeSource.Self }.ProvideValue(serviceProvider);
}
}
:私はXAML簡単にするMarkupExtensionとして作成することを決めましたこれらのプロパティ(Helper.FocusProperty) 間のロックの同期また、我々は結合性を持っている - ProvideValueメソッドでは、これはあなたが(MainWindow.Data
で例えばTextBox.Text
)ソースとターゲットのプロパティをバインドするために使用することを結合さ たち:
Helper.FocusProperty
とFrameworkElement.IsKeyboardFocusWithinProperty
は、それが双方向Helper.TargetProperty
XAMLへ
返すBindingExpression(Data
変更後のプロパティを更新するために)にするために、元の結合を更新
をupdetsロックする結合ます次のようになります。 <StackPanel>
<TextBox Text="{local:SynchronizationHelper Binding={Binding Data, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}}"/>
<TextBox Text="{local:SynchronizationHelper Binding={Binding Data, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}}"/>
<TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}, Path=Data}"></TextBlock>
</StackPanel>
And the short video demonstrating the result
希望の動作が何であるかは不明です。フォーカスが移動したコントロールをスキップするか、バウンドプロパティの更新をスキップしますか?値が変更されている場合次の同期フェーズで、スキップされた値はどうなりますか? – Dennis
私は、目的の動作を指定する段落を追加しました=) – Andre
これは興味深い問題です。ユーザーが編集中で、フィールドを更新する必要があるときはどうしますか?ユーザーはいつも勝つのですか?ユーザーの入力を待ち受け、ソースからの更新をブロックするカスタムBinding実装が必要なようです。 – Will