Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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在同一窗口中更改数据上下文和视图_Wpf_Mvvm - Fatal编程技术网

WPF在同一窗口中更改数据上下文和视图

WPF在同一窗口中更改数据上下文和视图,wpf,mvvm,Wpf,Mvvm,我是WPF am的新手,正在将一个应用程序从VC++6.0/MFC移植到c#/WPF(VS2013)。我的大部分windows开发都是在VC++/MFC中进行的。我正试图坚持MVVM模式,并编写一些概念验证应用程序,让我的脚湿透。到目前为止,我有一个症结 当我的应用程序启动时,它将显示客户和账单的树状视图。我使用一个简单的分层数据模板,将每个级别绑定到本地数据类型(视图模型),可以很好地实现这一点。我想做的是,当选中一张账单时(现在我在账单模板上有一个按钮可以按下),我想用账单的详细视图替换树状

我是WPF am的新手,正在将一个应用程序从VC++6.0/MFC移植到c#/WPF(VS2013)。我的大部分windows开发都是在VC++/MFC中进行的。我正试图坚持MVVM模式,并编写一些概念验证应用程序,让我的脚湿透。到目前为止,我有一个症结

当我的应用程序启动时,它将显示客户和账单的树状视图。我使用一个简单的分层数据模板,将每个级别绑定到本地数据类型(视图模型),可以很好地实现这一点。我想做的是,当选中一张账单时(现在我在账单模板上有一个按钮可以按下),我想用账单的详细视图替换树状视图(我不想弹出对话框)。

这方面的Xaml是:

   <DockPanel>
    <TreeView x:Name="trvGroups" ItemsSource="{Binding LBGroups}" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling">
    <TreeView.ItemContainerStyle>
        <!--
            This Style binds a TreeViewItem to a LBtreeViewItemViewModel
        -->
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
            <Setter Property="FontWeight" Value="Normal" />
        </Style>
    </TreeView.ItemContainerStyle>

    <TreeView.Resources>
        <HierarchicalDataTemplate
            DataType="{x:Type local:GroupViewModel}"
            ItemsSource="{Binding Children}"
            >
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding GroupName}" />
            </StackPanel>
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate 
            DataType="{x:Type local:BillViewModel}"
            ItemsSource="{Binding Children}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding BillName}" />
                <Button Command="{Binding Path=BillEditCommand}">Edit</Button>
            </StackPanel>
        </HierarchicalDataTemplate>
    </TreeView.Resources>
    </TreeView>
</DockPanel>

编辑
现在我的问题比什么都多。我应该将每个视图定义为用户控件并将它们放在window.resources中吗?我是否使用数据模板?我假设我将更改数据上下文以指向详细账单视图模型。最好的方法是什么

按照我的理解,我的目标是坚持MVVM,即代码中没有任何内容(或者尽可能少)

我正在寻找更多的指针,让我在研究的过程中沿着正确的道路开始。我现在有点糊涂了


提前感谢。

我将向您展示一个简单的主细节场景,您可以在树视图中选择模型并对其进行编辑

政务司司长:

public分部类主窗口:窗口,INotifyPropertyChanged
{
公共主窗口()
{
初始化组件();
this.DataContext=this;
}
专用ICommand onEditBillCommand;
public-ICommand-oneditbill命令
{
得到
{
if(onEditBillCommand==null)
onEditBillCommand=newrelaycommand
(
比尔=>{CurrentBill=bill;}
);
返回oneditbill命令;
}
}
私人汇票;
公众条例草案
{
获取{return currenctbill;}
设置
{
当前票据=价值;
房地产变更(即新的房地产变更担保(“当前票据”);
}
}
公开名单客户
{
得到
{
列出客户=新列表();
对于(int i=0;i<5;i++)
{
添加(CreateMockCustomer(i));
}
返回客户;
}
}
私人客户CreateMockCustomer(int g)
{
客户c=新客户();
c、 Name=“约翰(“+g+”);
对于(int i=0;i<3;i++)
{
c、 添加(CreateMockBill());
}
返回c;
}
私人条例草案
{
账单b=新账单();
b、 价格=55.5;
b、 BoughtOnDate=DateTime.Now.Date;
返回b;
}
公共事件PropertyChangedEventHandler PropertyChanged=委托{};
}
公共类客户:INotifyPropertyChanged
{
私有字符串名称;
公共字符串名
{
获取{返回名称;}
设置{name=value;}
}
私人收款票据;
公共收款票据
{
得到
{
如果(票据==null)
{
票据=新的可观测集合();
}
退票;
}
}
公共事件PropertyChangedEventHandler PropertyChanged=委托{};
}
公共类法案:INotifyPropertyChanged
{
私人双价;
公共双价
{
获取{返回价格;}
设置
{
价格=价值;
房地产变更(即新的房地产变更价格);
}
}
私人约会时间;
公共日期时间
{
获取{return boughtOnDate;}
设置
{
boughtOnDate=价值;
房地产变更(即新的房地产变更项目(“BoughtOnDate”);
}
}
公共事件PropertyChangedEventHandler PropertyChanged=委托{};
}
公共接口IRelayCommand:ICommand
{
void raisecannexectechanged();
}
公共类RelayCommand:IRelayCommand
{
私有谓词_canExecute;
私人行动——执行;
公共RelayCommand(操作执行,谓词canExecute=null)
{
_执行=执行;
_canExecute=canExecute;
}
私有void执行(T参数)
{
_执行(参数);
}
私有布尔CanExecute(T参数)
{
返回_canExecute==null?true:_canExecute(参数);
}
公共布尔CanExecute(对象参数)
{
返回参数==null?false:CanExecute((T)参数);
}
public void Execute(对象参数)
{
_执行((T)参数);
}
公共事件处理程序CanExecuteChanged;
public void raisecancecutechanged()
{
var temp=易失性读取(参考CanExecuteChanged);
如果(温度!=null)
temp(这是新的EventArgs());
}
}
XAML:

     <Window>
         <Window.Resources>
           <HierarchicalDataTemplate x:Key="customerTemplate" DataType="{x:Type local:Customer}" ItemsSource="{Binding Bills}">
               <HierarchicalDataTemplate.ItemTemplate>
                  <DataTemplate>
                    <Grid>
                       <Grid.ColumnDefinitions>
                           <ColumnDefinition/>
                           <ColumnDefinition/>
                           <ColumnDefinition/>
                       </Grid.ColumnDefinitions>

                       <TextBlock Text="{Binding Price}" />
                       <TextBlock Text="{Binding BoughtOnDate}" Grid.Column="1" />
                       <Button Content="Edit" Grid.Column="2"
                            Command="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext.OnEditBillCommand}" 
                            CommandParameter="{Binding}"/> 

                   </Grid>
               </DataTemplate>
           </HierarchicalDataTemplate.ItemTemplate>

           <TextBlock Text="{Binding Name}" FontFamily="Arial" FontSize="16" FontWeight="Bold" />

        </HierarchicalDataTemplate>

   </Window.Resources>

   <Grid>
       <Grid.ColumnDefinitions>
           <ColumnDefinition />
           <ColumnDefinition Width="0.05*"/>
           <ColumnDefinition />
       </Grid.ColumnDefinitions>


       <TreeView ItemsSource="{Binding Customers}" ItemTemplate="{StaticResource customerTemplate}">

       </TreeView>


       <Grid Grid.Column="2" DataContext="{Binding CurrentBill, Mode=OneWay}" Background="AliceBlue">
           <Grid.RowDefinitions>
              <RowDefinition />
              <RowDefinition />
           </Grid.RowDefinitions>

           <TextBox Text="{Binding Price, Mode=TwoWay}"  Margin="50"/>
           <TextBox Text="{Binding BoughtOnDate, Mode=TwoWay}" Grid.Row="1" Margin="50"/>


      </Grid>

   </Grid>     

每个视图都应该是
用户控件
(或
窗口
     <Window>
         <Window.Resources>
           <HierarchicalDataTemplate x:Key="customerTemplate" DataType="{x:Type local:Customer}" ItemsSource="{Binding Bills}">
               <HierarchicalDataTemplate.ItemTemplate>
                  <DataTemplate>
                    <Grid>
                       <Grid.ColumnDefinitions>
                           <ColumnDefinition/>
                           <ColumnDefinition/>
                           <ColumnDefinition/>
                       </Grid.ColumnDefinitions>

                       <TextBlock Text="{Binding Price}" />
                       <TextBlock Text="{Binding BoughtOnDate}" Grid.Column="1" />
                       <Button Content="Edit" Grid.Column="2"
                            Command="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext.OnEditBillCommand}" 
                            CommandParameter="{Binding}"/> 

                   </Grid>
               </DataTemplate>
           </HierarchicalDataTemplate.ItemTemplate>

           <TextBlock Text="{Binding Name}" FontFamily="Arial" FontSize="16" FontWeight="Bold" />

        </HierarchicalDataTemplate>

   </Window.Resources>

   <Grid>
       <Grid.ColumnDefinitions>
           <ColumnDefinition />
           <ColumnDefinition Width="0.05*"/>
           <ColumnDefinition />
       </Grid.ColumnDefinitions>


       <TreeView ItemsSource="{Binding Customers}" ItemTemplate="{StaticResource customerTemplate}">

       </TreeView>


       <Grid Grid.Column="2" DataContext="{Binding CurrentBill, Mode=OneWay}" Background="AliceBlue">
           <Grid.RowDefinitions>
              <RowDefinition />
              <RowDefinition />
           </Grid.RowDefinitions>

           <TextBox Text="{Binding Price, Mode=TwoWay}"  Margin="50"/>
           <TextBox Text="{Binding BoughtOnDate, Mode=TwoWay}" Grid.Row="1" Margin="50"/>


      </Grid>

   </Grid>