Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.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
按钮上的折叠/可见用户控件使用MVVM单击-无交换机制-_Mvvm_User Controls_Collapse - Fatal编程技术网

按钮上的折叠/可见用户控件使用MVVM单击-无交换机制-

按钮上的折叠/可见用户控件使用MVVM单击-无交换机制-,mvvm,user-controls,collapse,Mvvm,User Controls,Collapse,在我的场景中,我有一个MainView+MainView模型,UserControl1+usercontrol2。 在主视图中,我有两个按钮,标记为:Button\u ShowUserControl1+Button\u ShowUserControl2。 在主视图的下部,我有一个“ContentGrid”,它接受/应该接受。。。每个用户控制 我的目标: 单击按钮时,显示UserControl1UserControl1可见和UserControl2或任何其他UserControl1必须设置为折叠。

在我的场景中,我有一个MainView+MainView模型,UserControl1+usercontrol2。 在主视图中,我有两个按钮,标记为:Button\u ShowUserControl1+Button\u ShowUserControl2。 在主视图的下部,我有一个“ContentGrid”,它接受/应该接受。。。每个用户控制

我的目标:

单击按钮时,显示UserControl1UserControl1可见UserControl2或任何其他UserControl1必须设置为折叠。同样适用于按钮\u ShowUserControl2

我的问题:

<Grid x:Name="LayoutRoot" Background="#FFBDF5BD" ShowGridLines="False">
    <Grid.RowDefinitions>
        <RowDefinition Height="96*" />
        <RowDefinition Height="289*" />
    </Grid.RowDefinitions>      
    <Grid HorizontalAlignment="Stretch" Name="MenuGrid" VerticalAlignment="Stretch" Background="#FFCECEFF">
        <StackPanel Name="stackPanel1" Background="#FFEDFF00" Orientation="Horizontal">
            <Button Content="User Data 1" Height="35" Name="button1" Command="{Binding  Path=ShowUserControl1Command}" Width="150" Margin="100,0,0,0" />
            <Button Content="User Data 2" Height="35" Name="button2" Width="150" Margin="100,0,0,0" />
        </StackPanel>
    </Grid>
    <Grid Grid.Row="1" HorizontalAlignment="Stretch" Name="ContentGrid" VerticalAlignment="Stretch" Background="#FFB15454" />
</Grid>

<UserControl x:Class="SwapUserControls.MVVM.UserControl2"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         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" 
         xmlns:vm="clr-namespace:SwapUserControls.MVVM.ViewModel"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" Visibility="{Binding IsUserControl1Collapsed, Path=Value}">

<UserControl.Resources>
    <vm:MainViewModel x:Key="MainViewModelID" />
</UserControl.Resources>

<UserControl.DataContext>
    <Binding Source="{StaticResource MainViewModelID}" />
</UserControl.DataContext>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="228*" />
        <RowDefinition Height="72*" />
    </Grid.RowDefinitions>
    <Button Content="UserControl2" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="112,27,0,0" Name="button1" VerticalAlignment="Top" Width="75" />
    <DataGrid HorizontalAlignment="Stretch" Name="dataGrid1" VerticalAlignment="Stretch" Background="#FFC046F8" />
</Grid>
<Grid Visibility="Collapsed">
    <myControls:MyUserControl />
</Grid>
<Window ...>
<Window.Resources>
     <BooleanToVisibilityConverter x:Key="BoolToVis" />
</Window.Resources>

<Grid Visibility="{Binding ShouldShowUsercontrol1, Converter={StaticResource BoolToVis}}">
     <myControls:MyUserControl />
</Grid>
</Window>
1.)由于UserControls应在应用程序启动时加载,我如何将它们放在一个“ContentGrid”中?这实际上是不可能的。。。那么,如何使一个UserControl可见,而另一个在同一个位置/“ContentGrid”刚刚崩溃

2.)如1.)似乎不可能,如何在应用程序开始时实例化所有用户控件,并使它们仅在单击相应按钮时可见/折叠

3.)由于UserControl的属性Visibility=Visible/Hidden/Collazed,如何绑定到ViewModel中的属性并返回类似Collazed的值?我只能得到一个布尔值,比如Visibility=false/true

我的测试代码:

<Grid x:Name="LayoutRoot" Background="#FFBDF5BD" ShowGridLines="False">
    <Grid.RowDefinitions>
        <RowDefinition Height="96*" />
        <RowDefinition Height="289*" />
    </Grid.RowDefinitions>      
    <Grid HorizontalAlignment="Stretch" Name="MenuGrid" VerticalAlignment="Stretch" Background="#FFCECEFF">
        <StackPanel Name="stackPanel1" Background="#FFEDFF00" Orientation="Horizontal">
            <Button Content="User Data 1" Height="35" Name="button1" Command="{Binding  Path=ShowUserControl1Command}" Width="150" Margin="100,0,0,0" />
            <Button Content="User Data 2" Height="35" Name="button2" Width="150" Margin="100,0,0,0" />
        </StackPanel>
    </Grid>
    <Grid Grid.Row="1" HorizontalAlignment="Stretch" Name="ContentGrid" VerticalAlignment="Stretch" Background="#FFB15454" />
</Grid>

<UserControl x:Class="SwapUserControls.MVVM.UserControl2"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         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" 
         xmlns:vm="clr-namespace:SwapUserControls.MVVM.ViewModel"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" Visibility="{Binding IsUserControl1Collapsed, Path=Value}">

<UserControl.Resources>
    <vm:MainViewModel x:Key="MainViewModelID" />
</UserControl.Resources>

<UserControl.DataContext>
    <Binding Source="{StaticResource MainViewModelID}" />
</UserControl.DataContext>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="228*" />
        <RowDefinition Height="72*" />
    </Grid.RowDefinitions>
    <Button Content="UserControl2" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="112,27,0,0" Name="button1" VerticalAlignment="Top" Width="75" />
    <DataGrid HorizontalAlignment="Stretch" Name="dataGrid1" VerticalAlignment="Stretch" Background="#FFC046F8" />
</Grid>
<Grid Visibility="Collapsed">
    <myControls:MyUserControl />
</Grid>
<Window ...>
<Window.Resources>
     <BooleanToVisibilityConverter x:Key="BoolToVis" />
</Window.Resources>

<Grid Visibility="{Binding ShouldShowUsercontrol1, Converter={StaticResource BoolToVis}}">
     <myControls:MyUserControl />
</Grid>
</Window>

是的,代码是错误的,因此我在这里问:)

此代码只有两处错误

1)您不能直接设置usercontrol的可见性。。。您必须在容器上设置它:

<Grid x:Name="LayoutRoot" Background="#FFBDF5BD" ShowGridLines="False">
    <Grid.RowDefinitions>
        <RowDefinition Height="96*" />
        <RowDefinition Height="289*" />
    </Grid.RowDefinitions>      
    <Grid HorizontalAlignment="Stretch" Name="MenuGrid" VerticalAlignment="Stretch" Background="#FFCECEFF">
        <StackPanel Name="stackPanel1" Background="#FFEDFF00" Orientation="Horizontal">
            <Button Content="User Data 1" Height="35" Name="button1" Command="{Binding  Path=ShowUserControl1Command}" Width="150" Margin="100,0,0,0" />
            <Button Content="User Data 2" Height="35" Name="button2" Width="150" Margin="100,0,0,0" />
        </StackPanel>
    </Grid>
    <Grid Grid.Row="1" HorizontalAlignment="Stretch" Name="ContentGrid" VerticalAlignment="Stretch" Background="#FFB15454" />
</Grid>

<UserControl x:Class="SwapUserControls.MVVM.UserControl2"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         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" 
         xmlns:vm="clr-namespace:SwapUserControls.MVVM.ViewModel"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" Visibility="{Binding IsUserControl1Collapsed, Path=Value}">

<UserControl.Resources>
    <vm:MainViewModel x:Key="MainViewModelID" />
</UserControl.Resources>

<UserControl.DataContext>
    <Binding Source="{StaticResource MainViewModelID}" />
</UserControl.DataContext>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="228*" />
        <RowDefinition Height="72*" />
    </Grid.RowDefinitions>
    <Button Content="UserControl2" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="112,27,0,0" Name="button1" VerticalAlignment="Top" Width="75" />
    <DataGrid HorizontalAlignment="Stretch" Name="dataGrid1" VerticalAlignment="Stretch" Background="#FFC046F8" />
</Grid>
<Grid Visibility="Collapsed">
    <myControls:MyUserControl />
</Grid>
<Window ...>
<Window.Resources>
     <BooleanToVisibilityConverter x:Key="BoolToVis" />
</Window.Resources>

<Grid Visibility="{Binding ShouldShowUsercontrol1, Converter={StaticResource BoolToVis}}">
     <myControls:MyUserControl />
</Grid>
</Window>
然后,从“父视图”或“主视图”视图模型中,通过在视图模型集合中显示或隐藏所需的视图:

public MyMainViewModel : ViewModel
{
     public ObservableCollection<ViewModel> ViewsToShow
     {
          ...
     }

     public void ShowFirstViewModel()
     {
          ViewsToShow.Add(new MyFirstViewModel());
     }
}
以及对主视图的一些更改。为了简洁起见,我省略了数据模板

<Window ...>
     <!-- DataTemplates Here -->
     <Button Command="{Binding SwapViewsCommand}">Swap!</Button>
     <ContentControl Content="{Binding View}" />
</Window>

交换

就这样。这里的秘密是我正在保存对原始视图模型的引用。这样,假设viewmodel中有一个string属性,DataTemplated usercontrol中有一个关联的文本框,该文本框具有一个双向绑定,那么状态基本上会被保存。

这段代码只有两个错误

1)您不能直接设置usercontrol的可见性。。。您必须在容器上设置它:

<Grid x:Name="LayoutRoot" Background="#FFBDF5BD" ShowGridLines="False">
    <Grid.RowDefinitions>
        <RowDefinition Height="96*" />
        <RowDefinition Height="289*" />
    </Grid.RowDefinitions>      
    <Grid HorizontalAlignment="Stretch" Name="MenuGrid" VerticalAlignment="Stretch" Background="#FFCECEFF">
        <StackPanel Name="stackPanel1" Background="#FFEDFF00" Orientation="Horizontal">
            <Button Content="User Data 1" Height="35" Name="button1" Command="{Binding  Path=ShowUserControl1Command}" Width="150" Margin="100,0,0,0" />
            <Button Content="User Data 2" Height="35" Name="button2" Width="150" Margin="100,0,0,0" />
        </StackPanel>
    </Grid>
    <Grid Grid.Row="1" HorizontalAlignment="Stretch" Name="ContentGrid" VerticalAlignment="Stretch" Background="#FFB15454" />
</Grid>

<UserControl x:Class="SwapUserControls.MVVM.UserControl2"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         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" 
         xmlns:vm="clr-namespace:SwapUserControls.MVVM.ViewModel"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" Visibility="{Binding IsUserControl1Collapsed, Path=Value}">

<UserControl.Resources>
    <vm:MainViewModel x:Key="MainViewModelID" />
</UserControl.Resources>

<UserControl.DataContext>
    <Binding Source="{StaticResource MainViewModelID}" />
</UserControl.DataContext>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="228*" />
        <RowDefinition Height="72*" />
    </Grid.RowDefinitions>
    <Button Content="UserControl2" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="112,27,0,0" Name="button1" VerticalAlignment="Top" Width="75" />
    <DataGrid HorizontalAlignment="Stretch" Name="dataGrid1" VerticalAlignment="Stretch" Background="#FFC046F8" />
</Grid>
<Grid Visibility="Collapsed">
    <myControls:MyUserControl />
</Grid>
<Window ...>
<Window.Resources>
     <BooleanToVisibilityConverter x:Key="BoolToVis" />
</Window.Resources>

<Grid Visibility="{Binding ShouldShowUsercontrol1, Converter={StaticResource BoolToVis}}">
     <myControls:MyUserControl />
</Grid>
</Window>
然后,从“父视图”或“主视图”视图模型中,通过在视图模型集合中显示或隐藏所需的视图:

public MyMainViewModel : ViewModel
{
     public ObservableCollection<ViewModel> ViewsToShow
     {
          ...
     }

     public void ShowFirstViewModel()
     {
          ViewsToShow.Add(new MyFirstViewModel());
     }
}
以及对主视图的一些更改。为了简洁起见,我省略了数据模板

<Window ...>
     <!-- DataTemplates Here -->
     <Button Command="{Binding SwapViewsCommand}">Swap!</Button>
     <ContentControl Content="{Binding View}" />
</Window>

交换

就这样。这里的秘密是我正在保存对原始视图模型的引用。这样,假设viewmodel中有一个string属性,DataTemplated usercontrol中有一个关联的文本框,具有双向绑定,那么状态基本上会被保存。

当你说什么是不可能的时候,它会让事情变得有点混乱。。。试着坚持你的目标是什么。。。当我读到这些问题时,我有点不知所措,因为我试图解释它们的意思。我认为它们无关紧要,于是就去解决你的目标,但如果我错了,请纠正我。当你说不可能的话时,会让事情变得有点混乱。。。试着坚持你的目标是什么。。。当我读到这些问题时,我有点不知所措,因为我试图解释它们的意思。我认为它们与你的目标无关,并试图解决你的目标,但如果我错了,请纠正我。你好,安德森,我几乎按照你说的做了…:只剩下500个字符,所以=>我刚刚使用了一个按钮来切换用户控件,只是为了测试你的建议是否有效。我现在的问题是如何将8个用户控件放在同一个网格中,通过按顶部8个按钮中的一个来折叠/显示它们?如果我把所有的都放在StackPanel中,在应用程序启动时将它们全部设置为visibility=折叠,UserControl1除外,当我单击UC1时,我会每隔一次设置一次…不,这无法工作。每个UC都需要自己的网格使其可见/折叠?糊涂了@msfanboy看起来您正确理解了情况。当我在ViewModel中使用列表或ObservableCollection加载所有8个用户控件uc1、uc2、uc3等时,您看到解决方案了吗。。。实例添加到该集合中。然后,ContentGrid.Children属性将绑定到此集合。根据在菜单btn1、btn2、btn3等处按下的按钮。。。通过绑定到ViewModel属性,只有某个元素可见,其余元素将被折叠:)好主意还是坏主意?嗯,但是用户控件仍然需要每个人都有自己的网格……安德森先生,你知道吗;P@msfanboy当然,你可以很容易地做到这一点(ItemsControl+这个就可以了),但是这实际上有点模糊了视图和ViewModel之间的界限。。。我不推荐。WPF中的一个选项(据我所知不是Silverlight)是,您可以在ViewModel中拥有一组ViewModel,这些ViewModel使用正确的视图进行数据模板化。我将用这个例子编辑我的示例。@msfanboy这是一个特定于领域的策略,你必须自己想出。如果视图很少,那么跟踪索引可能是一种方法。如果你有很多,另一个策略可能是合适的。我想我没有足够的信息来真正帮助你。祝你好运。你好,安德森,我几乎按照你说的做了…:只剩下500个字符了,所以=>我刚刚使用了一个按钮来切换用户控件,只是为了测试你的建议是否有效。我现在的问题是如何将8个用户控件放在同一个网格中,通过按顶部8个按钮中的一个来折叠/显示它们?如果我把所有的都放在StackPanel中,在应用程序启动时将它们全部设置为visibility=折叠,UserControl1除外,当我单击UC1时,我会每隔一次设置一次…不,这无法工作。每个UC都需要自己的网格使其可见/折叠?糊涂了@Fanboy小姐看起来像你