- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我最近用 Binding Mode = OneWayToSource
做了很多测试,但我仍然不知道为什么会发生某些事情。
例如,我在类构造函数中为 dependency property
设置了一个值。现在,当 Binding 初始化时,Target
属性被设置为其默认值。意味着 dependency property
被设置为 null
并且我丢失了我在 constructor
中初始化的值。
为什么会这样? 绑定(bind)模式
并不像名称描述的那样工作。它应该只更新 Source
而不是 Target
代码如下:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MyViewModel();
}
private void OnClick(object sender, RoutedEventArgs e)
{
this.DataContext = new MyViewModel();
}
}
这是 XAML:
<StackPanel>
<local:MyCustomControl Txt="{Binding Str, Mode=OneWayToSource}"/>
<Button Click="OnClick"/>
</StackPanel>
这是我的自定义控件:
public class MyCustomControl : Control
{
public static readonly DependencyProperty TxtProperty =
DependencyProperty.Register("Txt", typeof(string), typeof(MyCustomControl), new UIPropertyMetadata(null));
static MyCustomControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl)));
}
public MyCustomControl()
{
this.Txt = "123";
}
public string Txt
{
get { return (string)this.GetValue(TxtProperty); }
set { this.SetValue(TxtProperty, value); }
}
}
这是 View 模型:
public class MyViewModel : INotifyPropertyChanged
{
private string str;
public string Str
{
get { return this.str; }
set
{
if (this.str != value)
{
this.str = value; this.OnPropertyChanged("Str");
}
}
}
protected void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null && propertyName != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
最佳答案
this.Txt = "123";
这是用本地值替换您的绑定(bind)。参见 dependency property value precedence .您实际上是在调用 DependencyObject.SetValue
当你真的想要DependencyProperty.SetCurrentValue
.此外,您需要等到生命周期后期才执行此操作,否则 WPF 将更新 Str
两次:一次使用“123”,然后再次使用 null
:
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
this.SetCurrentValue(TxtProperty, "123");
}
如果您在用户控件的构造函数中执行此操作,它会在 WPF 实例化它时执行,但会在 WPF 加载、反序列化和应用您的 BAML 时立即被替换。
更新:抱歉,我误解了你的确切问题,但现在有一个复制品,复制如下。我遗漏了您随后更新 DataContext
的部分。我通过在数据上下文更改时设置当前值来解决此问题,但在单独的消息中。否则,WPF 会忽略将更改转发到您的新数据源。
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
namespace SO18779291
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.setNewContext.Click += (s, e) => this.DataContext = new MyViewModel();
this.DataContext = new MyViewModel();
}
}
public class MyCustomControl : Control
{
public static readonly DependencyProperty TxtProperty =
DependencyProperty.Register("Txt", typeof(string), typeof(MyCustomControl), new UIPropertyMetadata(OnTxtChanged));
static MyCustomControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl)));
}
public MyCustomControl()
{
this.DataContextChanged += (s, e) =>
{
this.Dispatcher.BeginInvoke((Action)delegate
{
this.SetCurrentValue(TxtProperty, "123");
});
};
}
public string Txt
{
get { return (string)this.GetValue(TxtProperty); }
set { this.SetValue(TxtProperty, value); }
}
private static void OnTxtChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
Console.WriteLine("Changed: '{0}' -> '{1}'", e.OldValue, e.NewValue);
}
}
public class MyViewModel : INotifyPropertyChanged
{
private string str;
public string Str
{
get { return this.str; }
set
{
if (this.str != value)
{
this.str = value; this.OnPropertyChanged("Str");
}
}
}
protected void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null && propertyName != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
XAML:
<Window x:Class="SO18779291.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SO18779291"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<local:MyCustomControl Txt="{Binding Str, Mode=OneWayToSource}"/>
<Button x:Name="setNewContext">New Context</Button>
<TextBlock Text="{Binding Str, Mode=OneWay}"/>
</StackPanel>
</Window>
关于c# - 绑定(bind) OneWayToSource - 奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18779291/
我正在使用 OneWayToSource绑定(bind),它似乎总是将我的源属性设置为空。为什么呢?这给我带来了麻烦,因为我需要源属性中目标属性的值而不是空值。 这是我的代码: MyViewModel
我有一个 RadioButton其 IsChecked 的元素属性绑定(bind)到 MyProperty在 ViewModel . Binding有模式OneWayToSource由于某些原因,它会
为什么 OneWayToSource 绑定(bind)会重置我的目标值?这是绑定(bind)代码: SolidColorBrush brush = GetTemplateChild("PART_Pre
我最近用 Binding Mode = OneWayToSource 做了很多测试,但我仍然不知道为什么会发生某些事情。 例如,我在类构造函数中为 dependency property 设置了一个值
我有一个自定义控件,它具有以下依赖属性 public static readonly DependencyProperty PrintCommandProperty = DependencyPrope
我有 EntitiesUserControl 负责 EntitiesCount 依赖属性: public static readonly DependencyProperty EntitiesCoun
是否可以在我的模型中使用 OneWay 模式将 TextBox Text 字段绑定(bind)到属性 TextView,并绑定(bind)到另一个属性 TextInput 模式为 OneWayToSo
我需要编写一个看起来像 TextBox 的自定义控件,它包含一个名为 Refresh() 的方法,其主要目的是清除文本并回滚一些其他值。 该方法应以某种方式变得可绑定(bind),以便其他人可以将其
我在一个窗口中有一个 TextBox,我使用以下简单的转换器将其绑定(bind)到一个值: public class TestConverter : MarkupExtension, IValueCo
我正在尝试以 OneWayToSource 作为模式绑定(bind)到 Readonly 属性,但似乎无法在 XAML 中完成: 我得到: The property 'FlagThingy.IsMo
我有一个只读属性,需要在文本框中显示,并在运行时收到此错误。我设置了 IsEnabled="False"、IsReadOnly="True" - 没有运气。其他搜索说只读应该修复它,但不适合我。我有一
我正在使用 MVVM 模式并在运行我的应用程序时收到以下信息 无效操作异常TwoWay 或 OneWayToSource 绑定(bind)无法对“ViewModel.SynergyViewModel”
我对特定的 xaml 数据绑定(bind)有疑问。我有两个列表框(主要细节,所以列表框将 IsSynchronizedWithCurrentItem 设置为 true)。我希望我的 View 模型知道
当我设置目标控件的 DataContext 时,我有一个 OneWayToSource 绑定(bind),其行为不符合我的预期。源的属性被设置为默认值,而不是目标控件的属性值。 我在标准 WPF 窗口
我最近在代码中将 OneWayToSource 绑定(bind)添加到 View 模型中的只读属性。当时我不知道 .Net 4 的变化,当没有 getter 时这会导致异常: ... public
我有这个 xaml 文本框 绑定(bind)到这个属性: public double? Min { get { return min; }
OneWayToSource .NET 4.0 中的绑定(bind)似乎已损坏 我有这个简单的 Xaml 我的代码是这样的 public MainWindow() {
以下出现在数据模板中: 设置SelectedIndex 后(如上所示),绑定(bind)到Value 的OneWayToSource 不起作用。如果我不设置 SelectedIndex,则可以绑定(
我有一个绑定(bind)到 People 集合的 DataGrid。我还有一个 TextBox,它应该接受所选行中的 Name 值。然后用户可以编辑该值或保留原样。关键点是:TextBox 中显示的文
我是一名优秀的程序员,十分优秀!