天道酬勤,学无止境

WPF 简单绑定到 INotifyPropertyChanged 对象(WPF Simple Binding to INotifyPropertyChanged Object)

问题

我创建了最简单的绑定。 绑定到后面代码中的对象的文本框。

事件虽然 - 文本框仍然是空的。

设置了窗口的 DataContext,并且存在绑定路径。

你能说有什么问题吗?

XAML

<Window x:Class="Anecdotes.SimpleBinding"
        x:Name="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="SimpleBinding" Height="300" Width="300" DataContext="MainWindow">
    <Grid>
        <TextBox Text="{Binding Path=BookName, ElementName=TheBook}" />
    </Grid>
</Window>

背后的代码

   public partial class SimpleBinding : Window
    {
        public Book TheBook;

        public SimpleBinding()
        {
            TheBook = new Book() { BookName = "The Mythical Man Month" };
            InitializeComponent();
        }
    }

图书对象

public class Book : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }

    }

    private string bookName;

    public string BookName
    {
        get { return bookName; }
        set
        {
            if (bookName != value)
            {
                bookName = value;
                OnPropertyChanged("BookName");
            }
        }
    }
}
回答1

首先删除DataContext="MainWindow"因为这会将WindowDataContext设置为string MainWindow ,然后为绑定指定ElementName ,它将绑定源定义为另一个控件,其中x:Name="TheBook"在您的Window中不存在. 您可以通过从绑定中删除ElementName=TheBook以及通过将DataContext (如果未指定,则为默认源)分配给TheBookWindow来使您的代码工作

public SimpleBinding()
{
    ...
    this.DataContext = TheBook;
} 

或通过将绑定的RelativeSource指定到公开TheBookWindow

<TextBox Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=TheBook.BookName}"/>

但由于您无法绑定到字段,您需要将TheBook转换为属性:

public partial class SimpleBinding : Window
{
    public Book TheBook { get; set; }
    ...
}

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • WPF:简单的TextBox数据绑定(WPF: simple TextBox data binding)
    问题 我有这个课: public partial class Window1 : Window { public String Name2; public Window1() { InitializeComponent(); Name2 = new String('a', 5); myGrid.DataContext = this; } // ... } 我想在文本框中显示字符串Name2 。 <Grid Name="myGrid" Height="437.274"> <TextBox Text="{Binding Path=Name2}"/> </Grid> 但是不会显示该字符串。 另外,如果使用TimerCallback定期更新字符串Name2 ,我是否需要做任何事情来确保在数据更改时文本框得到更新? 回答1 Name2是一个字段。 WPF仅绑定到属性。 更改为: public string Name2 { get; set; } 请注意,使用此最小实现,您的TextBox将不会响应对Name2的编程更改。 因此,对于您的计时器更新方案,您需要实现INotifyPropertyChanged: partial class Window1 : Window, INotifyPropertyChanged { public event
  • 真正简单的WPF表单数据验证-如何?(Really simple WPF form data validation - how to?)
    问题 我有一个非常简单的类,我们称之为客户。 看起来像这样: namespace TestValidation { class Customer { private string _name; public string Name { get { return _name; } set { _name = value; if (String.IsNullOrEmpty(value)) { throw new Exception("Customer name is mandatory."); } } } } } 现在,我创建了一个基本表单,用户可以在其中将客户添加到数据库中。 该表单包含绑定到Customer的Name属性的简单TextBox,以及一个“添加”按钮。 XAML代码是: <Window x:Class="TestValidation.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:TestValidation" Title="MainWindow" Height="350" Width="525">
  • ListBox 到字符串 ObservableCollection 的简单 WPF 数据绑定(Simple WPF DataBinding of a ListBox to an ObservableCollection of strings)
    问题 好吧,我就是不明白。 请告诉我为什么我的 ListBox 中没有任何项目(现在应该是两个字符串“empty”和“stuff”): XAML: <Window.DataContext> <Windows:SettingsWindowModel x:Name="model"/> </Window.DataContext> <Window.Resources> <DataTemplate x:Key="ListItemTemplate"> <ListBoxItem Content="{Binding}" /> </DataTemplate> </Window.Resources> <ListBox Name="listBoxActivities" SelectionChanged="ListBoxActivitiesSelectionChanged" ItemsSource="{Binding Path=IgnoredActivities}" HorizontalAlignment="Left" VerticalAlignment="Top" MinHeight="40" MinWidth="200" Padding="5,100,5,0" Height="100" Margin="0,207,0,0" ItemTemplate="{StaticResource
  • 绑定可以在WPF中造成内存泄漏吗?(Can bindings create memory leaks in WPF?)
    问题 为了防止内存泄漏,我是否需要在项目消失时取消绑定项目? 我想我只是有点担心,如果我重新加载并将新模板应用于控件,并且该模板中存在与外部元素的绑定,是否可以防止为模板制作的控件被垃圾回收? 回答1 如果您未绑定到DependencyProperty或实现INotifyPropertyChanged的对象,则该绑定可能会泄漏内存,完成后您将必须取消绑定。 这是因为如果对象不是DependencyProperty或未实现INotifyPropertyChanged则它将通过PropertyDescriptors AddValueChanged方法使用ValueChanged事件。 这将导致CLR创建一个从PropertyDescriptor到object的强引用,并且在大多数情况下,CLR将在全局表中保留对PropertyDescriptor的引用。 因为绑定必须继续侦听更改。 当目标保持使用状态时,此行为使PropertyDescriptor和object之间的引用保持活动状态。 这可能会导致该object以及该object引用的任何object的内存泄漏。这包括数据绑定目标。 简而言之,如果您要绑定到DependencyProperty或INotifyPropertyChanged对象,则应该没问题,否则像任何已订阅的事件一样,您应该取消订阅绑定 编辑:有可能使用弱事件/引用在
  • 如何绑定一个ObservableCollection 到WPF中的复选框列表框(How to bind an ObservableCollection<bool> to a Listbox of Checkboxes in WPF)
    问题 首先,我要说明我对C#和WPF都是陌生的。 我正在尝试将Boolean值的集合连接到包含6个复选框的容器,并在按下按钮时存储这些值的状态。 我假设有一种简单的方法,因为将复选框绑定到的集合似乎是很自然的事情,但是到目前为止,我所看到的所有解决方案似乎都过于复杂(例如:http:// merill。 net / 2009/10 / wpf-checked-listbox /)。 我通过修改数据模板创建的复选框, ListBox和设置ItemsSource中的ListBox到ObservableCollection ,但我的问题是,我不知道该怎么绑定IsChecked来,因为我试图将其绑定到集合中的实际对象,而不是对象的属性。 回答1 使用IsChecked="{Binding}"直接绑定集合的项目。 <ListBox ItemsSource="{Binding MyBooleanCollection}" > <ListBox.ItemTemplate> <DataTemplate> <CheckBox IsChecked="{Binding Mode=OneWay}"/> </DataTemplate> </ListBox.ItemTemplate> </ListBox> 但是,无法使用此方法绑定到源。 因为CheckBox的IsChecked属性上的绑定不是绑定项的索引。
  • ICommand绑定导致WPF应用程序中的UI内存泄漏(ICommand binding causing UI memory leak in WPF application)
    问题 我正在构建一个WPF应用程序,该应用程序使用LINQ to SQL连接到SQL Server数据库。 该应用程序的主窗口包含一个ListView其中包含一系列详细信息视图。 ListView的ItemSource绑定到详细信息视图模型对象的集合,这些对象作为根视图模型的属性公开。 每个详细信息视图模型对象都包含几个ICommand属性以及一个公开详细模型对象的属性,该属性又公开了UI中显示的各种数据字段。 使用ANTS内存分析器进行的分析表明,泄漏的对象是详细模型对象中包含的对象,以及它们绑定到的一些UI类。 这些对象的先前刷新实例没有被垃圾回收。 ANTS有一个工具,允许用户跟踪参考链以识别为什么保留了不需要的内存。 使用它时,我发现显示的所有链条中都包含一个ICommand 。 因此,我删除了令人讨厌的ICommand ,发现内存泄漏消失了。 不幸的是,我需要ICommand来实现一些重要的功能。 真正令我困惑的是,它最初是如何引用详细模型对象的-它们是详细视图模型对象中的两个完全独立的实例变量。 这是详细视图模型对象的构造函数(对RootViewModel的引用用于连接到ICommands的某些方法中的回调。我最初怀疑这可能会导致循环引用链,这可能是导致问题,但是将其删除似乎没有任何效果。) public CarDataViewModel(CarData
  • WPF 与 .NET 对象的绑定不传递数据(WPF binding with .NET object not communicating the data)
    问题 我正在学习有关 WPF 数据绑定的教程。 我正在尝试将 .NET 对象的属性绑定到 XAML 控件,但该控件不显示预期的数据。 这些是我认为的相关代码部分: 在程序代码中:(注意:在原始帖子后删除了 PhotoGallery 中的 ObservableCollection) Namespace PhotoGallery Partial Public Class MainWindow Inherits Window Private photos As New Photos ... End Class Namespace PhotoGallery Public Class Photos Inherits Collection(Of Photo) ... End Class 在 XAML 中(解决方案/项目名称是 Ch13-PhotoGallery): <Window x:Class="PhotoGallery.MainWindow" ... xmlns:local="clr-namespace:Ch13_PhotoGallery.PhotoGallery" ...> <Window.Resources> <local:Photos x:Key="Photos"/> </Window.Resources> 这是不显示数据的控件,即照片集合的大小: <Label x:Name=
  • 在TextBlock中绑定在WPF中不起作用(Binding in TextBlock doesn't work in WPF)
    问题 我想动态更改班级中的TextBlock文本。 XAML代码: <TextBlock Name="Footer_text" Text=""/> C# : string footerMainMenuText = "Setting"; Binding set = new Binding(""); set.Mode = BindingMode.OneWay; set.Source = footerMainMenuText; Footer_text.DataContext = footerMainMenuText; Footer_text.SetBinding(TextBlock.TextProperty, set); 我检查了最后一行,并且Footer_text.Text设置正确。 ( Footer_text.Text="Setting" ),但是我的应用程序中的TextBlock不显示“ Setting”。 这里有什么问题? 回答1 如果您具有约束力-为什么不只在XAML中这样做呢? 查看您的代码是没有意义的-您最好还是去吧 Footer_text.Text = "Setting"; 理想情况下,您应该在XAML中执行此操作,或者至少提供一些使其绑定到的内容 <TextBlock Text="{Binding SomeProperty}" /> 我不确定为什么要自己将“字符串
  • ViewModel中的INotifyPropertyChanged与DependencyProperty(INotifyPropertyChanged vs. DependencyProperty in ViewModel)
    问题 在Model-View-ViewModel体系结构WPF应用程序中实现ViewModel时,似乎有两个主要选择来使它可数据绑定。 我已经看到了将DependencyProperty用于View要绑定的属性的实现,并且我已经看到ViewModel改为实现了INotifyPropertyChanged 。 我的问题是,什么时候我应该优先选择另一个? 有性能差异吗? 将ViewModel依赖项提供给WPF真的是一个好主意吗? 做出设计决策时,我还需要考虑什么? 回答1 肯特(Kent)撰写了有关该主题的有趣博客:视图模型:POCO与DependencyObjects。 简短的摘要: DependencyObjects未标记为可序列化 DependencyObject类重写并密封Equals()和GetHashCode()方法 DependencyObject具有线程相似性–只能在创建它的线程上访问 我更喜欢POCO方法。 可以在以下位置找到实现INotifyPropertyChanged接口的PresentationModel(也称为ViewModel)的基类:http://compositeextensions.codeplex.com 回答2 根据WPF性能指南,DependencyObjects的性能肯定比实现INotifyPropertyChanged的POCO更好:
  • WPF:什么会导致绑定源不更新?(WPF: What can cause a binding source to not be updated?)
    问题 我有一种情况,我不确定如何调试。 我希望有人可以建议为什么它可能不起作用并指出我正确的方向。 我有一个来自数据库的 TIFF 图像,它作为System.Data.Linq.Binary类型的属性公开。 我想在ItemsControl显示该 TIFF 图像的各个帧,因此我编写了一个转换器,该转换器采用 Binary 数据类型并返回 BitmapFrames 的ObservableCollection 。 我正在使用转换器以及"Mode=TwoWay"和"UpdateSourceTrigger=PropertyChanged"将ItemsControl.ItemsSource绑定到 Binary 属性。 图像的显示工作正常。 问题是,如果我向集合中添加一个框架,显示会更新,但该更改不会传输回源对象中的 Binary 属性。 我的转换器中的ConvertBack()方法从未被调用(向我表明绑定甚至从未尝试更新源)。 如果我手动调用BindingExpression.UpdateSource()就好像它设置为"UpdateSourceTrigger=Explicit" ,Binary 属性会正确更新。 因此,如果为"Mode=TwoWay"和"UpdateSourceTrigger=PropertyChanged"设置了绑定,并且对象实现了INotifyPropertyChanged
  • WPF中的双向绑定(Two-way binding in WPF)
    问题 我无法在WPF中进行双向绑定工作。 我的应用程序主窗口中有一个字符串属性,该属性绑定到TextBox(我将模式设置为“ TwoWay”)。 TextBox的值唯一会更新的时间是在窗口初始化时。 当我在TextBox中键入内容时,基础字符串属性值不会更改。 当字符串属性的值由外部源更改(例如,Click上的事件仅重置TextBox的值)时,更改不会传播到TextBox。 即使在这个几乎微不足道的示例中,我也必须执行哪些步骤才能使双向绑定正常工作? 回答1 很可能您正在尝试绑定到.net CLR属性,而不是WPFDependencyProperty(除其他功能外,它还提供更改通知)。 对于普通的CLR属性,您需要实现INotifyPropertyChanged并在PropertyChanged的事件处理程序中的文本框上强制更新。 因此,使具有属性的对象实现此接口,并在属性设置器中引发事件。 (所以现在我们有财产变更通知) 确保将对象设置为UI元素/控件的DataContext属性 当我开始学习WPF数据绑定时,这也使我失望。 更新:好吧,OP,如果我在错误的树上吠叫,那将是浪费时间。现在无论如何,因为您不得不挖掘一点..您会记住很长一段时间了。 这是完善此答案的代码段。 还发现更新文本框会在我退出后自动发生。
  • WPF 如何绑定 ComboBox(WPF How To Bind ComboBox)
    问题 我正在尝试将我的 ComboBox 绑定到字符串列表,并且我希望它在加载 Window 后显示默认值。 为此,我创建了一个 ViewModel 类,如: namespace MyData { class ViewModel { public ViewModel() { this.Name = ""; this.Age = 0; this.Address = ""; this.DateOfPurchase = DateTime.Now.AddDays(-30); this.CarModel = "VW"; //I want to set VW as default but options are Mazda, VW, Audi } public IEnumerable<String> CarModels { get { var carModels = new String[] {"Mazda", "VW", "Audi"}; //CarModel = cars.FirstOrDefault(car => CarModel == "VW"); //this is not needed return carModels; } } public string Name { get; set; } public int Age { get; set; } public string
  • C# WPF 绑定不从属性中获取数据(C# WPF binding doesn't take data from Property)
    问题 在我的 XAML 中,我正在执行以下操作 <Label Content="{Binding ElementName=Root, Path=UserData.Email, Mode=OneWay}" /> Root元素是我的Window本身,而UserData是一个get; private set; get; private set; auto 属性在我的代码隐藏文件中, Email属性是 get-only 并且是string类型。 UserData对象在用户登录后设置。但绑定没有从对象中获取值。 我已经验证该对象确实包含正确的数据并且不是null 。 我在这里缺少什么? 回答1 我继续为此创建了一个 hello world 版本。 这是xml。 当单击按钮到文本框中的文本时,这应该简单地更改横幅。 我找不到一个超级简单的例子,所以我只做了一个。 显然有更高级的方法可以做到这一点,但它应该是一个简单的版本来构建。 <Window x:Class="Hello_World.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow"
  • Wpf 数据绑定文本块未更新 [重复](Wpf Databound TextBlock not updating [duplicate])
    问题 这个问题在这里已经有了答案: 绑定在没有 INotifyPropertyChanged 的​​情况下工作,为什么? (1 个回答) 3年前关闭。 我有一个带有滑块和两个文本块的简单 WPF 窗口。 当滑块移动时,它会更新数据绑定对象。 现在第一个文本块更新而第二个没有。 为什么? 您可能会说这里没有 INotifyPropertyChanged。 但是为什么是第一次更新呢? 我已经把头发拉得够多了。 请帮忙。 我的 WPF 应用程序的所有荣耀如下。 <Window x:Class="DataTriggerDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:DataTriggerDemo" mc:Ignorable="d" Title=
  • 数据绑定到 WPF 中的方法(Databinding to a method in WPF)
    问题 我在将TextBox.Text属性数据绑定到对象的方法时遇到问题。 这个想法是允许用户在TextBox写入一个文件名,然后有一个TextBlock输出该文件的扩展名。 class GetFileInfo { public string GetFileExtension(string fileName) { return Path.GetExtension(fileName); } } 这是我的 XAML: <Window.Resources> <ObjectDataProvider x:Key="getFileInfo" MethodName="GetFileExtension" ObjectType="{x:Type local:GetFileInfo}"> <ObjectDataProvider.MethodParameters> <sys:String>abc.text</sys:String> </ObjectDataProvider.MethodParameters> </ObjectDataProvider> </Window.Resources> <StackPanel> <TextBox Name="textBox1"> <TextBox.Text> <Binding Source="{StaticResource getFileInfo}" Path=
  • wpf麻烦在UserControl中使用依赖项属性(wpf trouble using dependency properties in a UserControl)
    问题 我做了一个UserControl,它打算每隔几秒钟使用来自串行端口的数据进行更新。 该UserControl应该非常简单,由一个用于字段名称的标签和另一个包含该字段值的标签组成。 我说这应该很简单,但是不起作用。 它根本不更新,甚至不显示字段名称。 下面是代码: public partial class LabeledField : UserControl { public LabeledField() { InitializeComponent(); } public string fieldName { get { return fieldNameLabel.Content.ToString(); } set { fieldNameLabel.Content = value; } } public string fieldValue { get { return (string)GetValue(fieldValueProperty); } set { SetValue(fieldValueProperty, value); } } public static readonly DependencyProperty fieldValueProperty = DependencyProperty.Register( "fieldValue", typeof(string)
  • WPF和XAML的隐藏功能?(Hidden features of WPF and XAML?)
    问题 已锁定。 该问题及其答案被锁定,因为该问题是题外话,但具有历史意义。 它目前不接受新的答案或互动。 这是为各种语言讨论的大量隐藏功能。 现在,我对XAML和WPF的某些隐藏功能感到好奇吗? 我发现的一个是ListView的标题单击事件 <ListView x:Name='lv' Height="150" GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler"> GridViewColumnHeader.Click属性未列出。 到目前为止的一些相关功能: 多重绑定结合StringFormat TargetNullValue绑定 TextTrimming属性标记扩展向窗口添加航空效果先进的“字幕”属性 XAML转换器 也可以看看: C#的隐藏功能 Python的隐藏功能 ASP.NET的隐藏功能 Perl的隐藏功能 Java的隐藏功能 VB.NET的隐藏功能 PHP的隐藏功能 Ruby的隐藏功能 C的隐藏功能等等........ 回答1 多重绑定(与StringFormat结合使用): <TextBlock> <TextBlock.Text> <MultiBinding StringFormat="{}{0}, {1}"> <Binding Path="LastName" /> <Binding Path=
  • WPF绑定不更新视图(WPF binding not updating the view)
    问题 我有一个文本块: <TextBlock HorizontalAlignment="Left" Name="StatusText" Margin="0,20" TextWrapping="Wrap" Text="{Binding StatusText}"> ... Status ... </TextBlock> 代码背后: public StatusPage() { InitializeComponent(); this.DataContext = new StatusPageViewModel(this); } 并在viewModel中: private string _statusText; /// <summary> /// Status text /// </summary> public string StatusText { get { return _statusText; } set { _statusText = value; } } 并在viewModel中的功能: string statusText = Status.GetStatusText(); this.StatusText = statusText; GetStatusText()返回字符串像从功能等数值assinged到“做工作” this
  • 如何在Visibility属性上执行简单的XAML(WPF)条件绑定(How to do a simple XAML (WPF) conditional binding on the Visibility property)
    问题 我有一个带有属性的视图模型: public class MyModel { public bool IsEnabled {get;set;} } 我想使用此属性来切换按钮状态。 如果布尔值为true,我想隐藏按钮,否则显示它。 我尝试过类似的事情: <Button Visibility= "{Binding IsEnabled ? Hidden : Visible }">Enable</Button> 但这不适合。 我尝试了一些更复杂的解决方案,但我的猜测是,我缺少一些琐碎的东西。 有什么建议么? 回答1 由于您要在“ Hidden和“ Visible之间切换,而true处于隐藏状态,因此您可以编写自定义IValueConverter或使用简单的Style.Trigger <Button Content="Enable"> <Button.Style> <Style TargetType="{x:Type Button}"> <Setter Property="Visibility" Value="Visible"/> <Style.Triggers> <DataTrigger Binding="{Binding IsEnabled}" Value="True"> <Setter Property="Visibility" Value="Hidden"/> <
  • Wpf 将 TextBlock 绑定到 App 属性的成员(Wpf Binding a TextBlock to App Property's member)
    问题 在我的 WPF 应用程序中,我希望全局使用一个对象“CaseDetails”,即所有窗口和用户控件。 CaseDetails 实现 INotifyPropertyChanged,并具有属性 CaseName。 public class CaseDetails : INotifyPropertyChanged { private string caseName, path, outputPath, inputPath; public CaseDetails() { } public string CaseName { get { return caseName; } set { if (caseName != value) { caseName = value; SetPaths(); OnPropertyChanged("CaseName"); } } } protected virtual void OnPropertyChanged(string propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } public event