Wpf 如何在数据模板中实例化ViewModel
我是WPF、universal apps等领域的新开发人员 我创建了一个显示问题的视图 我有一个QuestionsViewModel,它公开了一个问题集合。在XAML中,我使用ItemsControl来显示问题 现在在DataTemplate中,我想使用一个用户控件来显示问题,实例化我的QuestionViewModel,将当前问题绑定到它,并将视图模型设置为用户控件的上下文。我的问题是,{Binding}没有给我一个问题,我有一个Binding对象:/ 我应该那样做吗? 如何在ViewModel中获取当前问题Wpf 如何在数据模板中实例化ViewModel,wpf,xaml,data-binding,win-universal-app,Wpf,Xaml,Data Binding,Win Universal App,我是WPF、universal apps等领域的新开发人员 我创建了一个显示问题的视图 我有一个QuestionsViewModel,它公开了一个问题集合。在XAML中,我使用ItemsControl来显示问题 现在在DataTemplate中,我想使用一个用户控件来显示问题,实例化我的QuestionViewModel,将当前问题绑定到它,并将视图模型设置为用户控件的上下文。我的问题是,{Binding}没有给我一个问题,我有一个Binding对象:/ 我应该那样做吗? 如何在ViewMode
代码
公共类问题:实体,IQuestion
{
公开问题(字符串标题,字符串答案):base()
{
这个.Title=Title;
这个答案=答案;
}
公共字符串标题{get;set;}
公共字符串答案{get;set;}
}
公共类问题视图模型:BaseViewModel
{
私有字符串描述;
公共问题viewmodel()
{
ObservableCollection问题=新的ObservableCollection();
questions.CollectionChanged+=questions\u CollectionChanged;
问题=问题;
AddQuestionCommand=新的AddQuestionCommand(问题);
AddQuestionCommand.Execute(null);//为测试添加问题
}
私有无效问题\u CollectionChanged(对象发送方,System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
Description=String.Format(“{0}个问题)”,Questions.Count);
}
公共ICollection问题{get;private set;}
公共ICommand AddQuestionCommand{get;private set;}
公共字符串描述{
获取{返回说明;}
设置
{
描述=值;
不动产变更(“说明”);
}
}
}
公共类问题视图模型:BaseViewModel
{
私人问题;
公共问题视图模型()
{
}
公共问题{get;set;}
}
问题视图
<UserControl x:Class="Question_Answer.View.Control.QuestionsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Question_Answer.Model"
xmlns:uc="using:Question_Answer.View.Control"
xmlns:vm="using:Question_Answer.ViewModel.Control"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<UserControl.DataContext>
<vm:QuestionsViewModel Description="view description"> </vm:QuestionsViewModel>
</UserControl.DataContext>
<ItemsControl Name="Questions" Grid.Row="1" Grid.ColumnSpan="2" ItemsSource="{Binding Questions}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="model:Question">
<uc:QuestionItemControl>
<uc:QuestionItemControl.DataContext>
<vm:QuestionViewModel Question="{Binding}" />
</uc:QuestionItemControl.DataContext>
</uc:QuestionItemControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</UserControl>
问题用户控制
<UserControl
x:Class="Question_Answer.View.Control.QuestionItemControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Question_Answer.View.Control"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Question.Title}" />
<TextBlock Grid.Column="1" Text="{Binding Question.Answer}" />
</Grid>
您的代码中有一些东西需要修改 我直接做了一个代码示例供您参考
public class QuestionsViewModel:ViewModelBase
{
private String description;
public ObservableCollection<Question> questions { get; set; }
public QuestionsViewModel()
{
questions = new ObservableCollection<Question>();
questions.CollectionChanged += Questions_CollectionChanged;
questions.Add(new Question("t1","a1"));
}
private void Questions_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
Description = String.Format("{0} question(s)", e.NewItems.Count);
}
public String Description
{
get { return description; }
set
{
description = value;
RaisePropertyChanged("Description");
}
}
}
public class QuestionViewModel:ViewModelBase
{
private Question question;
public QuestionViewModel()
{
}
public Question Question
{
get { return question; }
set
{
question = value;
RaisePropertyChanged("Question");
}
}
}
公共类问题viewmodel:ViewModelBase
{
私有字符串描述;
公共可观察收集问题{get;set;}
公共问题viewmodel()
{
问题=新的可观察集合();
questions.CollectionChanged+=questions\u CollectionChanged;
添加(新问题(“t1”、“a1”);
}
私有无效问题\u CollectionChanged(对象发送方,System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
Description=String.Format(“{0}个问题)”,e.NewItems.Count);
}
公共字符串描述
{
获取{返回说明;}
设置
{
描述=值;
RaiseProperty变更(“说明”);
}
}
}
公共类问题ViewModel:ViewModelBase
{
私人问题;
公共问题视图模型()
{
}
公众问题
{
获取{返回问题;}
设置
{
问题=价值;
RaiseProperty变更(“问题”);
}
}
}
要绑定的目标属性应该是依赖属性:
但是您应该在这里做的是让QuestionItemControl从ItemsControl中的父元素继承DataContext。只需避免在ItemsControl中显式设置QuestionItemControl的DataContext属性:
<ItemsControl Name="Questions" Grid.Row="1" Grid.ColumnSpan="2" ItemsSource="{Binding Questions}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="model:Question">
<uc:QuestionItemControl />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
…并直接绑定到QuestionItemControl.xaml中的标题和答案属性:
<UserControl
x:Class="Question_Answer.View.Control.QuestionItemControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Question_Answer.View.Control"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Title}" />
<TextBlock Grid.Column="1" Text="{Binding Answer}" />
</Grid>
</UserControl>
这应该是可行的,因为每个QuestionItemControl的DataContext实际上是ItemsControl的ItemsSource中的一个
Question
对象。最后,我将使用QuestionViewModel的集合而不是Question。这可能意味着要将问题集合与QuestionViewModel同步…Post code forAddQuestionCommand
类。问题集合中是否有问题?是的,我有一个问题,“AddQuestionCommand.Execute(null);”添加问题您好,谢谢您的回答。我以前做过类似的“QuestionItemControl”,但问题是上下文是一个问题,而不是QuestionViewModel。显示字段是可以的,但如果我想添加逻辑,如编辑或删除问题,我不能直接从模型中执行。我的问题是如何让一个带有当前问题的QuestionViewModel作为我的用户控件“QuestionItemControl”@PortePoisse Jerryway的数据上下文是正确的。您应该使用任何其他方法来访问模型级别的viewmodel命令。。就像您可以使用RelativeSource绑定来绑定命令一样。或者你会想到任何更好的方法..Thx,那么最后我不应该有一个QuestionItemControl的视图模型?因为这就是阻碍我的原因…是的。它应该只继承默认情况下的DataContext。
<Page
x:Class="AppMvvm2.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AppMvvm2"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<local:QuestionsControl></local:QuestionsControl>
</Grid>
<ItemsControl Name="Questions" Grid.Row="1" Grid.ColumnSpan="2" ItemsSource="{Binding Questions}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="model:Question">
<uc:QuestionItemControl />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<UserControl
x:Class="Question_Answer.View.Control.QuestionItemControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Question_Answer.View.Control"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Title}" />
<TextBlock Grid.Column="1" Text="{Binding Answer}" />
</Grid>
</UserControl>