收起/ ON按钮点击与MVVM可见用户控件 - 没有交换机制 -
-
21-09-2019 - |
题
在我的情况我有一个的MainView + MainViewModel,+的UserControl1用户控件2。 在我的MainView有2个按钮标记为:Button_ShowUserControl1 + Button_ShowUserControl2。 在我的MainView的下部有一个“ContentGrid”这需要/ should_take ...每用户控件。
我的目标:强>
当Button_ShowUserControl1被点击的的UserControl1 强>是<强>可见和<强> UserControl2 强> OR 的任何其他用户控件必须设置为<强>折叠即可。同样是有效的Button_ShowUserControl2。
我的问题:强>
1)。由于用户控件应在应用程序中加载启动我怎么才能把它们放在一起在一个“ContentGrid”?那实际上不可能的......所以我怎样才能使一个用户控件可见的,而另一个是在同一个地方/“ContentGrid”刚刚崩溃?
我怎么可以实例所有用户控件在应用程序的启动,使他们只可见/折叠点击相应的按钮时,2)为1)似乎不可能?
3)。作为一个用户控件具有属性Visibility =可见/隐藏/折叠的,我怎样才能结合在一个ViewModel属性返回这样一个值样折叠的?我只能得到这样的能见度=假/真?
一个布尔值我testcode:强>
<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>
public class MainViewModel : ViewModelBase
{
RelayCommand _ShowUserControl1Command;
private bool _IsUserControl1Collapsed;
public RelayCommand ShowUserControl1Command
{
get
{
if (_ShowUserControl1Command == null)
{
_ShowUserControl1Command = new RelayCommand( () => ShowUserControl1() );
}
return _ShowUserControl1Command;
}
}
public void ShowUserControl1()
{
_IsUserControl1Collapsed = true;
}
public bool IsUserControl1Collapsed
{
get
{
return _IsUserControl1Collapsed;
}
}
}
是该代码是错误的,因此,我请这里:)
解决方案
您只需要2个东西不对的代码。
1),则不能设置直接在用户控件的知名度......你必须将其设置在容器上:
<Grid Visibility="Collapsed">
<myControls:MyUserControl />
</Grid>
<强> 2)能见度不是一个布尔值,它是一个枚举。因此,你需要使用一个转换器转换成从布尔能见度。观察:强>
<Window ...>
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVis" />
</Window.Resources>
<Grid Visibility="{Binding ShouldShowUsercontrol1, Converter={StaticResource BoolToVis}}">
<myControls:MyUserControl />
</Grid>
</Window>
这应该是它。希望这有助于。
有其他的事情,你要离开有关的线索可能会影响这一工作的能力。例如,你不显示的最大容器元素......你包裹在一个StackPanel一切吗?如果在网格包裹的一切,例如,控制将在层覆盖一切。
尝试这些变化,我建议......它应该让你更接近。
修改:使用数据的另一种想法模板强>
您可以做的是确保另一件事,你有一个独特的视图模型为每个要显示这些意见和隐藏:
public class MyFirstViewModel : ViewModel
{
}
public class MySecondViewModel : ViewModel
{
}
然后从你的“父母”和“主”视图模型,可以显示或隐藏你想凭借的ViewModels的集合中有他们的看法:
public MyMainViewModel : ViewModel
{
public ObservableCollection<ViewModel> ViewsToShow
{
...
}
public void ShowFirstViewModel()
{
ViewsToShow.Add(new MyFirstViewModel());
}
}
要线材一切在你看来,你会那么的DataTemplate这些类型与他们的用户控件(但这不会导致被实例化这些观点,除非他们需要:
<Window ...>
<Window.Resources>
<DataTemplate DataType="{x:Type myViewModels:MyFirstViewModel}">
<myViews:MyFirstView />
</DataTemplate>
<DataTemplate DataType="{x:Type myViewModels:MySecondViewModel}">
<myViews:MySecondView />
</DataTemplate>
</Window.Resources>
<ItemsControl ItemsSource="{Binding ViewsToShow}" />
</Window>
和为你把“ViewsToShow”任何的ViewModels,显示将自动发现和模板在相应的视图。同样,不受真实需要之前实例化它。
这可能是比把一切都放到单一的东西在查看和设置知名度干净了一点,但你有一个独特的视图模型类型,为每个视图,这可能并非如此这将是相关的。
使用DataTemplated方法时节省状态的问题出现。这里的解决办法是踩你的视图模型作为控制的状态,并设计既您的ViewModels和你的浏览相应。这里是一个可以让你换出您的视图中使用DataTemplating,但来回切换的示例保存状态。
假定有从上一节瓦特已定义的DataTemplates / 2的ViewModels设置。让我们改变了MainViewModel一点:
public MyMainViewModel : ViewModel
{
public RelayCommand SwapViewsCommand
{
...
}
public ViewModel View
{
...
}
private ViewModel _hiddenView;
public MyMainViewModel()
{
View = new MyFirstViewModel();
_hiddenView = new MySecondViewModel();
SwapViewsCommand = new RelayCommand(SwapViewModels);
}
public void SwapViewModels()
{
var hidden = _hiddenView;
_hiddenView = View;
View = hidden;
}
}
和在主视图中的一些变化。我已经省略了的DataTemplates赘述。
<Window ...>
<!-- DataTemplates Here -->
<Button Command="{Binding SwapViewsCommand}">Swap!</Button>
<ContentControl Content="{Binding View}" />
</Window>
就是这样。这里的秘密是我保存参照原来的视图模型。通过这种方式,让我们说有一个视图模型一个字符串属性,并在DataTemplated用户控件与的双向关联的文本框结合,然后国家将主要被保存。