WPF绑定不会更新数据

时间:2014-11-16 19:35:08

标签: c# wpf mvvm binding

所以问题是,无论我在文本框中更改文本,我都不会更改代码中的属性,尽管我绑定它。 我使用MVVM模式,所以: 我的模特:

public class Shipment
{
    public Shipment() {}

    public int ShipmentId {get;set;}

    //LP and Payer
    [Required]
    public long ExternalNumber {get ; set;}
    public long MPKNumber { get; set; }
    public long ContractNumber { get; set; }
    public Payer Payer { get; set; }
    public Payment Payment { get; set; }
    //And much more but i'm working on these right now
}

我的ViewModel:

 public class PrepareNewViewModel : INotifyPropertyChanged
 {
    private Shipment shipment { get; set; }

    public Shipment Shipment
    {
        get
        {
            return shipment;
        }
        set
        {
            if (shipment != value)
            {
                shipment = value;
                RaisePropertyChanged("Shipment");
            }
        }
    } 

    public PrepareNewViewModel()
    {
        Shipment = new Shipment();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

我的观点:

<Page 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" 
      xmlns:Controls ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit" 
      xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" 
      x:Class="SmartShipping.Views.Pages.PrepeareNew" 
      xmlns:local ="clr-namespace:SmartShipping.ViewModels" 
      xmlns:System="clr-namespace:System;assembly=mscorlib" 
      xmlns:Model ="clr-namespace:SmartShipping.Model" 
      mc:Ignorable="d" 
      d:DesignHeight="889" d:DesignWidth="959" 
      Title="PrepeareNew">

    <Page.DataContext>
        <local:PrepareNewViewModel/>
    </Page.DataContext>

    <Page.Resources>
        <ObjectDataProvider x:Key="dataFromEnumPayer" MethodName="GetValues" ObjectType="{x:Type System:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="Model:Payer"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>

        <ObjectDataProvider x:Key="dataFromEnumPayment" MethodName="GetValues" ObjectType="{x:Type System:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="Model:Payment"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Page.Resources>

    <GroupBox Header="LIST PRZEWOZOWY I PŁATNIK" HorizontalAlignment="Left"
              VerticalAlignment="Top" Margin="10,131,0,0" Height="146" Width="458">
        <Grid HorizontalAlignment="Left" Width="448" Margin="0,0,-2,0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="28*"/>
                <ColumnDefinition Width="28*"/>
                <ColumnDefinition Width="56*"/>
            </Grid.ColumnDefinitions>

            <Label Content="Nr zewnętrzny:" HorizontalAlignment="Left" 
                   VerticalAlignment="Top" Margin="10,8,0,0" Width="138" Grid.ColumnSpan="2"/>
            <TextBox Height="24" Margin="10,31,10,0" TextWrapping="Wrap" 
                     Text="{Binding Shipment.ExternalNumber, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" 
                     VerticalAlignment="Top" Grid.ColumnSpan="2"/>

            <Label Content="Nr MPK:" HorizontalAlignment="Left" VerticalAlignment="Top" 
                   Margin="0,10,0,0" Grid.Column="2" Width="73"/>
            <TextBox Height="24" Margin="0,31,10,0" TextWrapping="Wrap" 
                     Text="{Binding Shipment.MPKNumber, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" 
                     VerticalAlignment="Top" Grid.Column="2" 
                     Background="{DynamicResource {x:Static SystemColors.ControlLightLightBrushKey}}"/>

            <Label Content="Płatnik usługi:" HorizontalAlignment="Left" 
                   VerticalAlignment="Top" Margin="10,69,0,0"/>
            <ComboBox ItemsSource="{Binding Source={StaticResource dataFromEnumPayer}}"  
                      Margin="10,92,0,0" VerticalAlignment="Top" Height="24" 
                      Background="{DynamicResource {x:Static SystemColors.ControlLightLightBrushKey}}"/>

            <Label Content="Forma płatności:" HorizontalAlignment="Left" 
                   VerticalAlignment="Top" Margin="5,69,0,0" Grid.Column="1"/>
            <ComboBox SelectedItem="{Binding Shipment.Payment}" 
                      ItemsSource="{Binding Source={StaticResource dataFromEnumPayment}}" 
                      Margin="10,92,10,0" VerticalAlignment="Top" Height="24" 
                      Background="{DynamicResource {x:Static SystemColors.ControlLightLightBrushKey}}" 
                      Grid.Column="1"/>

            <Label Content="Nr umowy:" HorizontalAlignment="Left" 
                   VerticalAlignment="Top" Margin="0,66,0,0" Grid.Column="2"/>
            <TextBox HorizontalAlignment="Left" Height="24" 
                     Margin="0,92,0,0" TextWrapping="Wrap" 
                     VerticalAlignment="Top" Width="214" Grid.Column="2" 
                     Text="{Binding Shipment.ContractNumber, ValidatesOnDataErrors=True}"/>
        </Grid>
    </GroupBox>
</Page>

难道我不能绑定模特的每一个属性吗?

2 个答案:

答案 0 :(得分:1)

MVVM的一个好的经验法则是ViewModel和View具有一对一的关系。如果你有每个Shipment成员的属性,那对我来说会更有意义。否则,Shipment的成员将不会更新。虽然直观地发货在技术上有所变化,但只有在更新其价值时才会更新属性 - 而不是其成员。

您的文本框在技术上仅限于一种方式。更改它们时,Shipment的成员不会更新。我很好奇,如果这是可能的,所以我在我正在进行的项目中自己测试它,并且确实改变了我的Model的成员没有处理RaisePropertyChanged。

答案 1 :(得分:0)

您需要在 View.cs 中设置数据上下文。像这样(最好在构造函数中):

this.DataContext=shipmentObject;