是否可以仅在WPF中使用触发器加载和卸载usercontrol

时间:2014-08-27 15:10:53

标签: wpf

我正在尝试创建MDI类功能,我希望加载与用户点击的按钮对应的用户控件并卸载其余部分。每个按钮都与userControl相关联

enter image description here

<Button Content="Worker registration"/> //UserControl1
<Button Content="Worker recognition"/>  //UserControl2 ...and so on

<Grid x:Name="UserControlManager"/>

2 个答案:

答案 0 :(得分:3)

有什么理由不使用tabcontrol?喜欢这个

<TabControl>
    <TabItem Header="Control A">
        <local:ControlA/>
    </TabItem>
    <TabItem Header="Control B">
        <local:UserControlB/>
    </TabItem>
</TabControl>

或使用ItemsSource绑定所有项目

<TabControl ItemsSource="{Binding MyItems}"/>

还有第三方TabControls非常好,就像一个devcomponents提供的那样。 如果TabControl不够(我知道很多问题),你可以使用IValueConverter将一些属性转换为视图。您可以使用Mediator和/或ViewModelLocator,我喜欢Galasoft的MVVM Light。他们通过nuget提供一切,甚至为您设置一切:)

为按钮添加命令,以选择要显示的内容。并添加xaml以显示SelectedControl。

Bad mediator / ViewmodelLocator;)使用I.E. Galasofts代替like in this post

public class ViewModelLocator : INotifyPropertyChanged
{
    private UserControl selectedControl;
    private ObservableCollection<UserControl> controls = new ObservableCollection<UserControl>();
    public UserControl SelectedControl
    {
        get { return selectedControl; }
        set 
        {
            if (Equals(selectedControl, value)) return;
            selectedControl = value;
            OnPropertyChanged();
        }
    }
    public ObservableCollection<UserControl> Controls
    {
        get { return controls; }
        set
        {
            if (Equals(controls, value)) return;
            controls = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

希望它有所帮助!

干杯

了Stian

答案 1 :(得分:1)

您可以使用DataTemplates根据您设置的数据(viweModel)加载视图

<Window.Resources>
    <ResourceDictionary>
        <DataTemplate DataType="{x:Type viewModel:ViewModel1}">
            <view:View1 />
        </DataTemplate>
        <DataTemplate DataType="{x:Type viewModel:ViewModel2}">
            <view:View2 />
        </DataTemplate>
    </ResourceDictionary>
</Window.Resources>

然后有一个ContentControl,您的内容将显示

<Grid >
    <ContentControl Content="{Binding MyContent}" />
</Grid

使用enumBooleanConverter(How to bind RadioButtons to an enum?)选择带有radiobuttons的枚举

<RadioButton GroupName="Navigation" 
         IsChecked="{Binding Path=SelectedNavigationEnum, 
                      Converter={StaticResource enumBooleanConverter},
                      ConverterParameter={x:Static viewModel:NavigationEnum.EnumValue1},
                      Mode=TwoWay}">Show View1</RadioButton>


<RadioButton GroupName="Navigation" 
         IsChecked="{Binding Path=SelectedNavigationEnum, 
                      Converter={StaticResource enumBooleanConverter},
                      ConverterParameter={x:Static viewModel:NavigationEnum.EnumValue2},
                      Mode=TwoWay}">Show View2</RadioButton>

更改SelectedNavigationEnum属性时,将MyContent属性设置为选定的viewModel

public NavigationEnum SelectedNavigationEnum
{
   ...
   set
   {
      ...  
      Navigate(value);

   }
}

protected void Navigate(NavigationEnum part)
{
    switch (part)
    {
        case NavigationEnum.EnumValue1:
            ShowView1();
            break;
        case NavigationEnum.EnumValue2:
            ShowView2();
        ...
    }
}

private void ShowView1()
{
    ViewModel1 viewModel = ObjectFactory.GetInstance<ViewModel1>();
    MyContent = viewModel;
}

设置MyContent时,DataTemplate将加载View1并将viewModel设置为其DataContext。