Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 如何在数据模板中实例化ViewModel_Wpf_Xaml_Data Binding_Win Universal App - Fatal编程技术网

Wpf 如何在数据模板中实例化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

我是WPF、universal apps等领域的新开发人员

我创建了一个显示问题的视图

我有一个QuestionsViewModel,它公开了一个问题集合。在XAML中,我使用ItemsControl来显示问题

现在在DataTemplate中,我想使用一个用户控件来显示问题,实例化我的QuestionViewModel,将当前问题绑定到它,并将视图模型设置为用户控件的上下文。我的问题是,{Binding}没有给我一个问题,我有一个Binding对象:/

我应该那样做吗? 如何在ViewModel中获取当前问题


代码

公共类问题:实体,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 for
AddQuestionCommand
类。问题集合中是否有问题?是的,我有一个问题,“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>