2012-02-16 62 views
2

为什么如果我将两个控件(例如2个TextBoxes)绑定到未实现INotifyPropertyChanged的模型的单个属性,两个文本框的内容保持同步?另一个TextBox如何被通知另一个更新源?将两个WPF控件绑定到一个模型属性是否创建共享绑定?

型号:

namespace BindingExample 
{ 
    public class PersonModel 
    { 
     public string Name { get; set; } 
    } 
} 

查看:

<Window x:Class="BindingExample.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:BindingExample" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <local:PersonModel x:Key="person"></local:PersonModel> 
     <Style TargetType="TextBox"> 
      <Setter Property="VerticalAlignment" Value="Center" /> 
      <Setter Property="Width" Value="100"/> 
     </Style>  
    </Window.Resources> 
    <Grid DataContext="{StaticResource person}"> 
     <Grid.RowDefinitions> 
      <RowDefinition/> 
      <RowDefinition/> 
     </Grid.RowDefinitions> 
     <TextBox Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}" /> 
     <TextBox Grid.Row="1" Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}"/> 
    </Grid> 
</Window> 
+1

你能显示你的代码吗?我会说这是预期的行为,但是你说你还没有实现'INotifyPropertyChanged' - 在这种情况下,我不希望'TextBox'要更新。 – ChrisF 2012-02-16 11:57:42

+0

@ChrisF最初期望绑定只读取源属性的值。 – Clemens 2012-02-16 12:03:19

+0

@Jason Sich是源属性也许是DependencyProperty,虽然这在模型类中会很奇怪。 – Clemens 2012-02-16 12:04:57

回答

1

在您的示例中的两个文本框都使用相同的datacontext,实际上共享.NET对象PersonModel的同一个实例,因为默认设置的资源字典中的静态资源是WPF 共享,即当引用到静态资源时,您将始终获得相同的实例。更多关于在X:MSDN上的共享属性:

MSDN article about x:Shared attribute

的替代品,这是设置X:共享为false,以每次得到一个新的实例。另外,我不得不在你的示例中删除绑定到datacontext,以便个别地编辑文本框中的值。

下面的XAML显示这一点:

<Window x:Class="WpfScrollToEndBehavior.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfScrollToEndBehavior" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.Resources> 
    <local:PersonModel x:Key="person" x:Shared="false" Name="John Doe"> </local:PersonModel> 
    <Style TargetType="TextBox"> 
     <Setter Property="VerticalAlignment" Value="Center" /> 
     <Setter Property="Width" Value="100"/> 
    </Style> 
</Window.Resources> 
<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition/> 
     <RowDefinition/> 
    </Grid.RowDefinitions> 
    <TextBox Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged, Source={StaticResource person}}" /> 
    <TextBox Grid.Row="1" Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged, Source={StaticResource person}}" /> 
</Grid> 

原因X:共享在资源字典中设置为true的资源是出于效率的考虑。通过在XAML中的资源字典中的资源(例如对象)上设置x:Shared,每次资源被引用和访问时,都会给我们新的实例。我必须从网格中删除数据上下文,并将文本框的绑定源设置为静态资源人员。

+0

感谢您的回答。我正在学习WPF,从我所知道的这种行为开始看起来不对。 – 2012-04-22 11:16:50

+1

答案“因为文本框共享相同的datacontext对象”并不能解释为什么两个文本框同步。 这将是如果PersonModel实现'INotifyPropertyChanged'的答案。但事实并非如此。 该过程如下所示: - 说textbox1.Text由用户更改。 - 它绑定到PersonModel.Name,因此它更新属性。 但是,textbox2.Text怎么知道这个Name属性的新值呢? PersonModel对象不通知其属性的更改。 – Lu55 2012-11-22 21:09:03