wpf 绑定到视图模型不起作用 mvvm
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18930271/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
binding to viewmodel not working mvvm
提问by Nadeem Shaikh
I am new to MVVM. I tried to create a simple program but am facing a problem. I have created a TokensViewModeland a page. But after binding controls I found that my execution does not go to TokensViewModel. Please tell me where I am going wrong. Here are the details:
我是 MVVM 的新手。我试图创建一个简单的程序,但遇到了一个问题。我创建了一个TokensViewModel和一个页面。但是在绑定控件后我发现我的执行没有转到TokensViewModel. 请告诉我哪里出错了。以下是详细信息:
Folder hierarchy is this way:
文件夹层次结构是这样的:
BusinessLogicLayer\TokenManager.cs
Commom\RelayCommand.cs
PresentationLayer\ViewModel\TokensViewModel.cs
PresentationLayer\Views\GenerateToken.xaml (Page)
ResourceAccessLayer\TokenRepository.cs
业务逻辑层\TokenManager.cs
Commom\RelayCommand.cs
PresentationLayer\ViewModel\TokensViewModel.cs
PresentationLayer\Views\GenerateToken.xaml(页面)
ResourceAccessLayer\TokenRepository.cs
RelayCommand.cs:
中继命令.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
TokenManager.cs
class TokenManager
{
public bool Add(token tokens)
{
return true;
}
}
GenerateToken.xaml
生成令牌.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
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
生成令牌.xaml.cs
public partial class GenerateToken : Page
{
public GenerateToken()
{
InitializeComponent();
}
}
Thank you in Advance.
先感谢您。
回答by Ed Chapel
You need to declare an instance of your TokensViewModelin the XAML:
您需要TokensViewModel在 XAML 中声明您的实例:
<Page ...
xmlns:ViewModels="clr-namespace:xyz.PresentationLayer.ViewModel">
<Page.Resources>
<ViewModels:TokensViewModel x:Key="ViewModel" />
</Page.Resources>
<Grid ... DataContext="{Binding Source={StaticResource ViewModel}}">
The XAML above creates an instance and adds it to the Page.Resourcesdictionary with a key of ViewModel.
上面的 XAML 创建了一个实例并将其添加到Page.Resources字典中,键为ViewModel。
Alternatively, you can set this in the code-behind if you name your Grid:
或者,如果您命名为Grid:
<Grid x:Name="LayoutRoot">
public GenerateToken()
{
InitializeComponent();
LayoutRoot.DataContext = new TokensViewModel();
}
The downside of binding it in code-behind is that in many circumstances, you get Intellisense and designer support when you establish the DataContextin the XAML. The reason for this is that the type of the DataContextis declared in XAML at design time. In the code-behind approach, the type is not known until run-time.
在代码隐藏中绑定它的缺点是,在许多情况下,当您DataContext在 XAML 中建立 时,您会获得智能感知和设计器支持。这样做的原因是DataContext设计时在 XAML 中声明了 的类型。在代码隐藏方法中,类型直到运行时才知道。
The Grid.DataContextis then bound to this instance of your TokensViewModel. The rest of your {Binding}in the controls within Gridinherit the DataContextsuch that you can bind with:
在Grid.DataContext随后被绑定到您的这个实例TokensViewModel。您{Binding}在控件中的其余部分Grid继承了DataContext您可以绑定的内容:
<TextBlock Name="lblName"
Text="{Binding Name}" />
回答by Nitin
You have not set the DataContextfor your page.
您还没有DataContext为您的页面设置。
trying doing
尝试做
DataContext = new TokensViewModel()after InitializeComponents()
DataContext = new TokensViewModel()在 InitializeComponents() 之后

