2013-09-21 136 views
4

我是MVVM的新手。我试图创建一个简单的程序,但面临一个问题。我创建了一个TokensViewModel和一个页面。但绑定控制后,我发现我的执行不会去TokensViewModel。请告诉我我哪里错了。下面是详细信息:绑定viewmodel不工作mvvm

文件夹层次结构是这样的:

BusinessLogicLayer \ TokenManager.cs

常见合\ RelayCommand.cs

表示层\视图模型\ TokensViewModel.cs

PresentationLayer \ Views \ GenerateToken.xaml(Page)

Reso urceAccessLayer \ TokenRepository.cs

RelayCommand.cs:

class RelayCommand:ICommand 
{ 
    readonly Action<object> _execute; 
    readonly Predicate<object> _canExecute; 
    public RelayCommand() { } 
    public RelayCommand(Action<object> execute, Predicate<object> canExecute) 
    { 
     _execute = execute; 
     _canExecute = canExecute; 
    } 

    public RelayCommand(Action<object> execute): this(execute, null) {} 

    public bool CanExecute(object parameter) 
    { 
     return _canExecute==null?true:_canExecute(parameter); 
    } 
    public event EventHandler CanExecuteChanged 
    { 
     add { CommandManager.RequerySuggested += value; } 
     remove{CommandManager.RequerySuggested-=value;} 
    } 
    public void Execute(object parameter) 
    { 
     _execute(parameter); 
    } 
} 

TokenManager.cs

class TokenManager 
{ 
    public bool Add(token tokens) 
    { 
     return true; 
    }   
} 

GenerateToken.xaml

<Page x:Class="xyz.GenerateToken" 
    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="800" d:DesignWidth="900" 
    xmlns:ViewModels="clr-namespace:xyz.PresentationLayer.ViewModel" 
    Title="GenerateToken"> 
    <Grid Height="750" Width="800"> 
    <TextBlock Height="23" HorizontalAlignment="Left" Margin="29,85,0,0" Name="lblName" Text="Name" VerticalAlignment="Top" FontSize="16" /> 
    <TextBlock FontSize="16" Height="23" HorizontalAlignment="Left" Margin="29,154,0,0" Name="lblPlateNumber" Text="Plate Number" VerticalAlignment="Top" /> 
    <TextBlock FontSize="16" Height="23" HorizontalAlignment="Left" Margin="29,226,0,0" Name="lblPancard" Text="Pancard Number" VerticalAlignment="Top" /> 
    <TextBlock FontSize="16" Height="23" HorizontalAlignment="Left" Margin="410,85,0,0" Name="lblContactNumber" Text="Contact Number" VerticalAlignment="Top" /> 
    <TextBlock FontSize="16" Height="23" HorizontalAlignment="Left" Margin="410,163,0,0" Name="lblAddres" Text="Address" VerticalAlignment="Top" Width="60" /> 
    <Button Content="Generate" Command="{Binding SaveCommand}" Height="34" HorizontalAlignment="Left" Margin="216,328,0,0" Name="btnGenerateToken" VerticalAlignment="Top" Width="133" FontSize="20" /> 
    <TextBox Height="32" HorizontalAlignment="Left" Margin="178,85,0,0" Text="{Binding Path=Name}" Name="txtName" VerticalAlignment="Top" Width="186" BorderThickness="2" FontSize="16" /> 
    <TextBox BorderThickness="2" Height="32" HorizontalAlignment="Left" Text="{Binding Path=PlateNumber}" Margin="178,154,0,0" Name="txtPlateNumber" VerticalAlignment="Top" Width="186" FontSize="16" /> 
    <TextBox BorderThickness="2" Height="32" HorizontalAlignment="Left" Text="{Binding Path=PanNumber}" Margin="178,226,0,0" Name="txtPanNumber" VerticalAlignment="Top" Width="186" FontSize="16" /> 
    <TextBox BorderThickness="2" Height="32" HorizontalAlignment="Left" Text="{Binding Path=ContactNumber}" Margin="580,85,0,0" Name="txtContactNumber" VerticalAlignment="Top" Width="194" FontSize="16" /> 
    <TextBlock Height="34" HorizontalAlignment="Left" Margin="29,12,0,0" Name="txtbTitle" Text="Generate Token" VerticalAlignment="Top" FontSize="22" Foreground="#FF1313D8" Width="165" /> 
    <Button Content="Clear All" FontSize="20" Height="34" HorizontalAlignment="Left" Margin="418,328,0,0" Name="btnClearAll" VerticalAlignment="Top" Width="133" /> 
    <TextBox Height="108" HorizontalAlignment="Left" Margin="580,166,0,0" Text="{Binding Path=Address}" Name="txtAddress" VerticalAlignment="Top" Width="194" /> 
    </Grid> 
</Page> 

TokensViewModel.cs

class TokensViewModel:INotifyPropertyChanged 
{ 
    #region Private Declaration 
    private readonly token tokObject; 
    private readonly ObservableCollection<token> _token; 
    private readonly TokenManager tokenManager; 
    private readonly ICommand _SaveCommand; 
    ModelDataContext dataContext = new ModelDataContext(); 
    #endregion 
    #region Constructor 
    public TokensViewModel() 
    { 
     tokObject = new token(); 
     tokenManager = new TokenManager(); 
     _token = new ObservableCollection<token>(); 
     _SaveCommand = new RelayCommand(save, CanAdd); 
    } 
    #endregion 
    #region SaveCommand 
    public bool CanAdd(object obj) 
    { 
     if (Name != string.Empty && Address != string.Empty && ContactNumber.ToString() != null && PanNumber != string.Empty && PlateNumber != string.Empty) 
      return true; 
     else 
      return false; 
    } 
    public void save(object obj) 
    { 
     dataContext.tokens.InsertOnSubmit(new token 
     { 
      vcrNameOfCustomer = Name, 
      address = Address, 
      contact_no = ContactNumber, 
      pan_no = PanNumber, 
      plate_no = PlateNumber 
     }); 
     dataContext.SubmitChanges(); 
    } 
    #endregion 
    #region Commands 
    public ICommand SaveCommand { get { return _SaveCommand; } } 
    #endregion 
    #region Properties 
    public int Id 
    { 
     get { return tokObject.token_id; } 
     set 
     { 
      tokObject.token_id = value; 
      onPropertyChanged("Id"); 
     } 
    } 
    public Int64 ContactNumber 
    { 
     get { return tokObject.contact_no; } 
     set 
     { 
      tokObject.contact_no = value; 
      onPropertyChanged("ContactNumber"); 
     } 
    } 
    public string Address 
    { 
     get { return tokObject.address; } 
     set 
     { 
      tokObject.address = value; 
      onPropertyChanged("Address"); 
     } 
    } 
    public string PanNumber 
    { 
     get { return tokObject.pan_no; } 
     set 
     { 
      tokObject.pan_no = value; 
      onPropertyChanged("PanNumber"); 
     } 
    } 
    public string PlateNumber 
    { 
     get { return tokObject.plate_no; } 
     set 
     { 
      tokObject.plate_no = value; 
      onPropertyChanged("PlateNumber"); 
     } 
    } 
    public string Name 
    { 
     get { return tokObject.vcrNameOfCustomer; } 
     set 
     { 
      tokObject.vcrNameOfCustomer = value; 
      onPropertyChanged("Name"); 
     } 
    } 
    public ObservableCollection<token> tokens { get { return _token; } } 
    #endregion 
    #region INotifyProperty Members 
    public event PropertyChangedEventHandler PropertyChanged; 
    public void onPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
    #endregion 
} 

GenerateToken.xaml.cs

public partial class GenerateToken : Page 
{ 
    public GenerateToken() 
    { 
     InitializeComponent(); 
    } 
} 

预先感谢您。

回答

5

您需要在XAML申报您的TokensViewModel的一个实例:

<Page ... 
    xmlns:ViewModels="clr-namespace:xyz.PresentationLayer.ViewModel"> 
    <Page.Resources> 
    <ViewModels:TokensViewModel x:Key="ViewModel" /> 
    </Page.Resources> 
    <Grid ... DataContext="{Binding Source={StaticResource ViewModel}}"> 

的XAML上面创建一个实例,并把它添加到字典Page.ResourcesViewModel的关键。

或者,你可以在你的名字设置此代码后您的Grid

<Grid x:Name="LayoutRoot"> 

public GenerateToken() 
{ 
    InitializeComponent(); 
    LayoutRoot.DataContext = new TokensViewModel(); 
} 

在结合它的缺点代码隐藏的是,在许多情况下,你的智能感知和设计师的支持时,您在XAML中建立DataContext。原因在于设计时在XAML中声明DataContext的类型。在代码隐藏方法中,类型直到运行时才知道。

Grid.DataContext然后绑定到您的TokensViewModel的这个实例。您{Binding}在控制范围内Grid其余继承DataContext,这样你可以用绑定:

<TextBlock Name="lblName" 
      Text="{Binding Name}" /> 
+0

谢谢你,先生,现在正在工作。 –

+0

@NadeemShaikh作为它的正确答案,值得将其标记为已接受的答案。从我+1 – kevchadders

1

您没有设置DataContext为您的网页。

试图InitializeComponents后做

DataContext = new TokensViewModel()()