- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试制作一个具有可绑定(bind)属性的示例 WPF 用户控件(也许说“开发人员控件”会更好)。我的代码由这些文件组成:
----- MainWindow.xaml -----
<Window x:Class="Test_Binding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:testBinding="clr-namespace:Test_Binding"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<testBinding:MyLabelledTextBox x:Name="MLTB" LabelText="My custom control: MyLabelledTextBox" Text="{Binding StringData, Mode=OneWay}" />
</StackPanel>
</Window>
----- MainWindow.xaml.cs -----
using System.Windows;
namespace Test_Binding
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
this.DataContext = new MyDataObject();
this.InitializeComponent();
}
}
}
----- MyDataObject.cs -----
using System.Runtime.CompilerServices; // CallerMemberName
using System.ComponentModel; // INotifyPropertyChanged
namespace Test_Binding
{
public class MyDataObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string stringData;
public string StringData
{
get { return this.stringData; }
set
{
if (value != this.stringData)
{
this.stringData = value;
this.OnPropertyChanged();
}
}
}
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public MyDataObject()
{
System.Timers.Timer t = new System.Timers.Timer();
t.Interval = 10000;
t.Elapsed += t_Elapsed;
t.Start();
}
private void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
this.StringData = ((this.StringData ?? string.Empty).Length >= 4 ? string.Empty : this.StringData + "*");
}
}
}
----- MyLabelledTextBox.xaml -----
<UserControl x:Class="Test_Binding.MyLabelledTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel Background="Yellow">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*" />
<ColumnDefinition Width="0.5*" />
</Grid.ColumnDefinitions>
<Label x:Name="MLTBLabel" Grid.Row="0" Grid.Column="0" />
<TextBox x:Name="MLTBTextBox" Grid.Row="0" Grid.Column="1" Background="Yellow" Text="{Binding Text, Mode=TwoWay}" />
</Grid>
</StackPanel>
</UserControl>
----- MyLabelledTextBox.xaml.cs -----
using System.Windows;
using System.Windows.Controls;
namespace Test_Binding
{
/// <summary>
/// Interaction logic for MyLabelledTextBox.xaml
/// </summary>
public partial class MyLabelledTextBox : UserControl
{
public static readonly DependencyProperty LabelTextProperty =
DependencyProperty.Register("LabelText", typeof(string), typeof(MyLabelledTextBox),
new PropertyMetadata(string.Empty, MyLabelledTextBox.LabelTextPropertyChanged));
public string LabelText
{
get { return (string)this.GetValue(MyLabelledTextBox.LabelTextProperty); }
set { this.SetValue(MyLabelledTextBox.LabelTextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(MyLabelledTextBox),
new PropertyMetadata(string.Empty, MyLabelledTextBox.TextPropertyChanged));
public string Text
{
get { return (string)this.GetValue(MyLabelledTextBox.TextProperty); }
set { this.SetValue(MyLabelledTextBox.TextProperty, value); }
}
public MyLabelledTextBox()
{
this.InitializeComponent();
this.MLTBLabel.DataContext = this;
this.MLTBTextBox.DataContext = this;
this.MLTBTextBox.TextChanged += new TextChangedEventHandler(this.MLTBTextBox_TextChanged);
}
private void MLTBTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
this.Text = this.MLTBTextBox.Text; // transfer changes from TextBox to bindable property (bindable property change notification will be fired)
}
private static void LabelTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((MyLabelledTextBox)d).MLTBLabel.Content = (string)e.NewValue; // transfer changes from bindable property to Label
}
private static void TextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((MyLabelledTextBox)d).MLTBTextBox.Text = (string)e.NewValue; // transfer changes from bindable property to TextBox
}
}
}
有一个“MyDataObject”类的实例,其属性为“StringData”,该实例使用计时器定期修改。我的用户控件绑定(bind)到它的属性“StringData”。如果“MainWindow.xaml”文件中的绑定(bind)设置为“TwoWay”,用户控件会不断更新,但如果我使用“OneWay”绑定(bind),则用户控件会更新一次,然后“PropertyChanged” “MyDataObject”类实例的事件不会再次触发,因为它突然没有订阅者。
为什么“OneWay”绑定(bind)在调用一次后就停止工作了?什么代码更改可以让“TwoWay”和“OneWay”绑定(bind)继续工作?
最佳答案
首先。
this.MLTBLabel.DataContext = this;
this.MLTBTextBox.DataContext = this;
不不不不!
从来没有。曾经。曾经。从代码隐藏设置您的 DataContext
。一旦这样做,您就失去了从父控件绑定(bind)到用户控件的依赖属性的神奇之美。换句话说,就是不要这样做。
这是你应该做的:
给你的 UserControl
一个 x:Name
。
<UserControl ...
x:Name="usr">
将您的 UserControl 的依赖属性绑定(bind)到您的元素,如下所示:
<TextBlock Text="{Binding MyDependencyProperty, ElementName=usr}" ... />
将您的 UserControl 的 DataContext 属性绑定(bind)到您的元素,如下所示:
<TextBlock Text="{Binding MyDataContextProperty}"/>
使用此方法将允许您在 MainWindow
中设置 UserControl
的 DataContext
,但仍然能够绑定(bind)到 UserControl 的UserControl 中的依赖属性。如果您在代码隐藏中设置 UserControl 的 DataContext,您将无法绑定(bind)到您的依赖属性。
现在,进入您的实际问题。
所有这些:
private void MLTBTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
this.Text = this.MLTBTextBox.Text; // transfer changes from TextBox to bindable property (bindable property change notification will be fired)
}
private static void LabelTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((MyLabelledTextBox)d).MLTBLabel.Content = (string)e.NewValue; // transfer changes from bindable property to Label
}
private static void TextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((MyLabelledTextBox)d).MLTBTextBox.Text = (string)e.NewValue; // transfer changes from bindable property to TextBox
}
算了吧。看来您正试图规避我之前谈到的不当行为。
你应该绑定(bind)到你的依赖属性:
<Label Grid.Row="0" Grid.Column="0" Text="{Binding Text, ElementName=usr}"/>
您遇到的另一个问题是,在您的 MainWindow
中,您在 UserControl
上使用了绑定(bind)。
Text="{Binding StringData, Mode=OneWay}"
现在,因为您已经在代码隐藏中设置了 DataContext
。这实际上是在说:
从当前控件的 DataContext 绑定(bind)到 StringData。
在您的情况下,这是与您的 MainWindow
DataContext 完全不同的绑定(bind)。 (因为您已经在 UserControl 中明确设置了 DataContext)。
运行我之前提到的内容。有很多东西要学,但这只是一个开始。
关于c# - WPF UserControl with Binding Mode=OneWay,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30560390/
我不知道该怎么做... function f1() { var x = 10; function f2(fx) { var x; x = 6;
早期绑定(bind)和后期绑定(bind)有什么区别? 最佳答案 简短的回答是,早期(或静态)绑定(bind)是指编译时绑定(bind),后期(或动态)绑定(bind)是指运行时绑定(bind)(例如
如何在 SwiftUI View 上使用 Binding(get: { }, set: { }) 自定义绑定(bind)与 @Binding 属性。我已成功使用此自定义绑定(bind)与 @State
我经常发现自己遇到问题,即控件的两个(相关)值被更新,并且两者都会触发昂贵的操作,或者控件可能会暂时处于不一致的状态。 例如,考虑一个数据绑定(bind),其中两个值 (x,y) 相互减去,最终结果用
我想通过我的 ViewModel 控制我的一个窗口的高度和宽度。 这看起来很简单。 但没有。它不起作用。 它检查 ViewModel 的 Width但不是 Height . 奇怪的是,如果我切换 W
UI5中一次性绑定(bind)和单向绑定(bind)有什么区别? 是否有任何用户特定的用例我会使用它们? 我无法从文档中获得太多信息。 最佳答案 单程 它的作用:单向数据流。模型数据的变化(例如通过
(define make (lambda (x) (lambda (y) (cons x (list y))))) (let ((x 7) (p (make 4))) (cons
尽管我或多或少地了解什么是语言绑定(bind),但我很难理解它们是如何工作的。 例如,谁能解释一下如何为 WinAPI 制作 Java 绑定(bind)? 最佳答案 如果您搜索 Foreign Fun
谁能解释为什么我可以重新绑定(bind)列表但不能+? (binding [list vector] (list 1 3)) (binding [list +] (list 1 3)) (bi
我真的很喜欢 Caliburn 和命名约定绑定(bind),我很惊讶 可见性与“CanNAME”约定用于保护 Action 的方式不同。 据我所知, BooleanToVisibilityConver
我了解动态绑定(bind)的实现方式以及静态绑定(bind)和动态绑定(bind)之间的区别,但我只是无法理解动态绑定(bind)的定义。基本上它是一种运行时绑定(bind)类型。 最佳答案 基本上,
http://jsfiddle.net/3NRsd/ var foo = $("div").bind("click", function() { $("div").animate({"hei
这个问题我快疯了...我有一个用户控件,它有一个用于插入操作的 FormView 和一个用于所有其他操作的 GridView。 在这两个控件中,我都有一个 DropDownList,如下所示: '
我有一个绑定(bind)到 ListBox 的地址的 ObservableCollection。然后在 ItemTemplate 中,我使用 {Binding .} 绑定(bind)到当前地址记录。这
如果我有以下简单的 js/knockout 代码: .js( View 模型): var image = ko.observable('http://placehold.it/300x150'); 看
我正在 aurelia 上开发一个自定义属性,让用户在输入文本区域时从列表中进行选择。例如,用法将是这样的: 正如您可能注意到的,auto-complete是属性。现在,当我想显示提示时,我想在自定
我正在使用 EventEmitter2作为我的应用程序内部的消息总线。现在我需要绑定(bind)和取消绑定(bind)一些事件处理程序。因为我也希望他们bind将它们添加到给定的上下文中,我最终得到以
我有以下函数调用: $(".selector").on("click", callback.bind(this, param1, param2)); 在我的回调函数中,我想使用绑定(bind)的 th
我目前正在试验新的编译绑定(bind),并且(再次)达到了我在拼图中遗漏了一个小问题:为什么我必须调用 Bindings.Update?直到现在,我还认为实现 INotifyPropertyChang
我正在阅读一本关于编写 JavaScript 框架的书,并找到了这段代码。但是我不明白它是如何工作的,尤其是 bind.bind 的用法?有人知道吗? var bind = Function.prot
我是一名优秀的程序员,十分优秀!