- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我需要从 ViewModel 将焦点设置到 UIElement 的附加属性。我创建了 Attached 属性,并在 PropertyChangedCallback 中将焦点设置到 UIElement。
private static void VoySetFocusChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
if (o is UIElement)
{
if ((bool)e.NewValue)
{
(o as UIElement).Focus();
(o as UIElement).SetValue(VoySetFocusProperty, false);
}
}
}
但我希望它像霰弹枪中的扳机一样工作。我在 ViewModel 中将 True 设置为 Test ... 它调用 MyAttachedProperties 类中的 PropertyChangedCallback,将焦点设置到 UIElement
((o as UIElement).Focus();
ViewModel中Test的值返回false
((o as UIElement).SetValue(VoySetFocusProperty, false);)
似乎一切正常,但 SetValue 并没有改变我在 ViewModel 中的值。
完整代码:
查看:
<Window x:Class="WpfAttachedProperty.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfAttachedProperty"
Title="MainWindow" Height="127" Width="316">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBox local:MyAttachedProperties.VoySetFocus="{Binding Path=Test,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Text="Focus Me"/>
<Button Grid.Row="1" Content="Click to Focus" HorizontalAlignment="Left" Margin="10" VerticalAlignment="Top" Width="75" Command="{Binding MyCommand}" />
</Grid>
代码隐藏:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfAttachedProperty
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow:Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
}
/// <summary>
/// Command Class
/// </summary>
public class DelegateCommand:ICommand
{
private readonly Action _action;
public DelegateCommand(Action action)
{
_action = action;
}
public void Execute(object parameter)
{
_action();
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged
{
add
{
}
remove
{
}
}
}
/// <summary>
/// ViewModelClass
/// </summary>
public class ViewModel:INotifyPropertyChanged
{
private bool _test = false;
public bool Test
{
get
{
return _test;
}
set
{
_test = value;
this.NotifyPropertyChanged("Test");
}
}
public ICommand MyCommand
{
get
{
return new DelegateCommand(SetTestToTrue);
}
}
private void SetTestToTrue()
{
this.Test = true;
}
#region INotifyPropertyChanged
public void NotifyPropertyChanged(String PropertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
public class MyAttachedProperties
{
public static Object GetVoySetFocus(DependencyObject obj)
{
return (Object)obj.GetValue(VoySetFocusProperty);
}
public static void SetVoySetFocus(DependencyObject obj, Object value)
{
obj.SetValue(VoySetFocusProperty, value);
}
public static readonly DependencyProperty VoySetFocusProperty =
DependencyProperty.RegisterAttached("VoySetFocus", typeof(bool), typeof(MyAttachedProperties), new UIPropertyMetadata(false, new PropertyChangedCallback(VoySetFocusChanged), new CoerceValueCallback(CoerceVoySetFocus)));
private static object CoerceVoySetFocus(DependencyObject d, object baseValue)
{
return (bool)baseValue;
}
private static void VoySetFocusChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
if (o is UIElement)
{
if ((bool)e.NewValue)
{
(o as UIElement).Focus();
// Doesn't set Test to false in ViewModel
(o as UIElement).SetValue(VoySetFocusProperty, false);
}
}
}
}
}
问候马可。
最佳答案
问题出在线路上:
((o as UIElement).SetValue(VoySetFocusProperty, false);)
您应该改用 SetCurrentValue 设置 DP。
((o as UIElement).SetCurrentValue(VoySetFocusProperty, false);)
解释:
直接设置任何 DependencyProperty 的值会破坏它与源属性的绑定(bind)。
但是,SetCurrentValue
不会破坏绑定(bind)并将值推回到源属性。 MSDN 对 SetCurrentValue 的解释:
This method is used by a component that programmatically sets the value of one of its own properties without disabling an application's declared use of the property. The SetCurrentValue method changes the effective value of the property, but existing triggers, data bindings, and styles will continue to work.
此外,我认为如果同步执行操作,在 PropertyChanged
回调中设置它不会将其传播回 Viewmodel,因为它仅从 Viewmodel 属性 setter 到达回调。
因此,我们可以做的是异步执行此操作,方法是使用 BeginInvoke
将它排入调度程序,以便它传播到 viewmodel 测试属性。
(o as UIElement).Focus();
Dispatcher.CurrentDispatcher.BeginInvoke((Action)delegate
{
// Doesn't set Test to false in ViewModel
(o as UIElement).SetCurrentValue(VoySetFocusProperty, false);
});
关于c# - 附属属性(property)。如何在 PropertyChangedCallback 中使用 SetValue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21863715/
我有一个用户控件,它有两个 DependencyProperties。每个 DependencyProperty 都有 PropertyChangedCallback。在设置属性值的顺序中调用回调很重
看起来 WPF 并不总是调用 DependencyProperty 的已注册 PropertyChangedCallback 过程。即使我们从 VM 手动引发 PropertyChanged 事件,W
这已经困扰我一段时间了,所以我问了一个同事他是否能理解它,现在我来了;) 为什么可以在依赖属性的 PropertyChangedCallback 中访问持有类的私有(private)成员? 让我通过这
我有一个 TextBox 绑定(bind)到一个依赖属性,我已经实现了一个 PropertyChangedCallBack 函数,当文本更改时我需要调用 textbox.ScrollToEnd() 但
如果有自己的用户控件,带有 DependencyProperty 和相应的回调方法,如下所示: public partial class PieChart : UserControl { pu
我有一个依赖属性和一个回调。 public static readonly DependencyProperty IsBusyProperty = DependencyProp
我有一个派生自 System.Windows.Controls.UserControl 的类,我需要将 PropertyChangedCallback 添加到 FrameworkElement.Mar
我创建了一个派生自 Canvas 的控件,它应该绘制一个实时图表,给定值通过绑定(bind)传递给 DependencyProperty。简化版是这样的: public class Plotter :
我有一个具有三个属性 (x1,x2,x3) 和该属性的 PropertyChangedCallback 的对象集合。 此集合绑定(bind)到 Wpf DataGrid。然后我想用像“x1+x2”这样
我有一个类的依赖属性,我们称它为“SomethingControl”: public static readonly DependencyProperty SomethingProperty = De
我有一个用户控件,它公开了一个名为 VisibileItems 的 DependencyProperty每次更新该属性时,我都需要触发另一个事件。为此,我添加了一个带有 PropertyChanged
我正在创建一个具有PropertyChangedCallback依赖项属性的WPF CustomControl。在该Callback方法中,我尝试使用GetTemplateChild()方法从OnAp
DependencyProperty.OverrideMetadata() 是否也覆盖了 PropertyChangedCallback? 最佳答案 取自此处:http://msdn.microsof
DependencyProperty.OverrideMetadata() 是否也覆盖了 PropertyChangedCallback? 最佳答案 取自此处:http://msdn.microsof
我的大体理解是,当属性发生变化时,会立即执行本地回调。所以我可以假设这会立即发生。但是,绑定(bind)属性的回调在绑定(bind)传播之前不会发生,这可能不会立即发生。这是正确的吗? 最佳答案 听起
我想在每次更改属性时执行一些代码。以下在一定程度上起作用: public partial class CustomControl : UserControl { public bool
我有一个带有文本框的用户控件和一个基本上是带有 CollectionView 的 ListBox 的自定义列表控件。我想使用 CollectionView 的过滤器功能并使用文本框中的文本来过滤可见元
我正在创建一个 WinRT CustomControl,它具有 PropertyChangedCallback 的依赖属性。在该回调方法中,我尝试为我使用 GetTemplateChild() 方法从
我的应用程序使用 MVVM 架构,ViewModel 不了解 View。当 ViewModel 对象需要显示新 View 时,它会公开一个公共(public) ShowNewView 属性,该属性是一
我需要从 ViewModel 将焦点设置到 UIElement 的附加属性。我创建了 Attached 属性,并在 PropertyChangedCallback 中将焦点设置到 UIElement。
我是一名优秀的程序员,十分优秀!