我是MVVM的新手。我试图创建一个简单的程序,但我遇到了问题。我创建了一个TokensViewModel
和一个页面。但是在绑定控件之后,我发现我的执行没有转到TokensViewModel
。请告诉我哪里出错了。以下是详细信息:
文件夹层次结构是这样的:
BusinessLogicLayer \ TokenManager.cs
常见合\ RelayCommand.cs
表示层\视图模型\ TokensViewModel.cs
PresentationLayer \ Views \ GenerateToken.xaml(Page)
ResourceAccessLayer \ 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();
}
}
先谢谢你。
答案 0 :(得分:6)
您需要在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.Resources
键将其添加到ViewModel
字典。
或者,如果您为Grid
命名
<Grid x:Name="LayoutRoot">
public GenerateToken()
{
InitializeComponent();
LayoutRoot.DataContext = new TokensViewModel();
}
在代码隐藏中绑定它的缺点是,在许多情况下,当您在XAML中建立DataContext
时,您将获得Intellisense和设计器支持。原因是DataContext
的类型在设计时在XAML中声明。在代码隐藏方法中,直到运行时才知道类型。
然后Grid.DataContext
绑定到TokensViewModel
的此实例。 {Binding}
内控件中Grid
的其余部分继承了DataContext
,以便您可以绑定:
<TextBlock Name="lblName"
Text="{Binding Name}" />
答案 1 :(得分:1)
您尚未为页面设置DataContext
。
尝试
在InitializeComponents()之后 DataContext = new TokensViewModel()