【问题标题】:Loading Views into ContentControl and changing their properties by clicking buttons将视图加载到 ContentControl 并通过单击按钮更改其属性
【发布时间】:2011-05-10 21:15:57
【问题描述】:

我有一个 mvvm(model view viewmodel) silverlight 应用程序,它有几个需要加载到 ContentControls 的视图(我在表达式混合中完成了这一切)。我不知道该怎么做,例如,通过单击另一个内容控件中的另一个视图中的按钮,在一个内容控件中加载一个视图(用户控件)。为了更容易理解问题,我需要做类似的事情:

http://www.codeproject.com/KB/silverlight/BlendableVMCom.aspx

不同之处在于 child1 和 child2 应该通过单击 Call child1 或 call child2 按钮加载到自己的内容控件中。

和示例将不胜感激。提前致谢!

【问题讨论】:

  • 查看 Caliburn Micro、屏幕和导体。

标签: silverlight mvvm expression-blend contentcontrol


【解决方案1】:

这个例子非常简化,但我想你现在如何调整它以适应你的应用程序。

主视图:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Border x:Name="commandsView">
        <Button Content="Call view 1" Command="{Binding CallView1Command}" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="5" />
    </Border>
    <Border x:Name="displayedView" Grid.Column="1">
        <ContentControl Content="{Binding CurrentView}" />
    </Border>
</Grid>

我没有创建单独的视图作为用户控件,这里只是边框,可以用真实的视图替换。

后台代码中不同视图的不同视图模型:

this.commandsView.DataContext = new CommandsViewModel();
this.displayedView.DataContext = new DisplayedViewModel();

第一个视图模型包含将消息发送到另一个视图模型的命令:

public class CommandsViewModel
{
    public CommandsViewModel()
    {
        this.CallView1Command = new RelayCommand(() => 
          Messenger.Default.Send<View1Message>(new View1Message()));
    }

    public RelayCommand CallView1Command { get; set; }

}

public class View1Message : MessageBase
{

}

要使此示例正常运行,请下载MVVM Light library

第二个视图模型接收消息并为其属性创建一个视图:

public class DisplayedViewModel : ViewModelBase
{
    public DisplayedViewModel()
    {
        Messenger.Default.Register<View1Message>(this, obj => 
            this.CurrentView = new TextBlock { Text = "Pressed the button 1 and now here is the view 1" });
    }

    private object currentView;

    public object CurrentView
    {
        get { return currentView; }
        set
        {
            currentView = value;
            RaisePropertyChanged("CurrentView");
        }
    }
}

同样,可以使用 clr 对象代替控件并在 xaml 中应用数据模板,但没有足够的空间来提供所有生成的代码。

就是这样,主要思想是某种事件聚合器,在这种特殊情况下是 Messenger 类。

如果没有 MVVM Light,它将需要更多代码:

public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();

        var events = new GlobalEvents();
        this.commandsView.DataContext = new CommandsViewModel(events);
        this.displayedView.DataContext = new DisplayedViewModel(events);
    }
}

public class GlobalEvents
{
    public event EventHandler View1Event = delegate { };

    public void RaiseView1Event()
    {
        View1Event(this, EventArgs.Empty);
    }
}

/// <summary>
/// Commands which call different views
/// </summary>
public class CommandsViewModel
{
    public CommandsViewModel(GlobalEvents globalEvents)
    {
        this.CallView1Command = new DelegateCommand(globalEvents.RaiseView1Event);
    }

    public DelegateCommand CallView1Command { get; set; }
}

/// <summary>
/// Model where views are changed and then displayed
/// </summary>
public class DisplayedViewModel : INotifyPropertyChanged
{
    public DisplayedViewModel(GlobalEvents globalEvents)
    {
        globalEvents.View1Event += (s,e) =>
            this.CurrentView = new TextBlock { Text = "Pressed the button 1 and now here is the view 1" };
    }

    private object currentView;

    public object CurrentView
    {
        get { return currentView; }
        set
        {
            currentView = value;
            RaisePropertyChanged("CurrentView");
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

}

在此示例中,您必须将 DelegateCommand 类更改为不同的内容。其他代码适用于所有人。

【讨论】:

  • 感谢示例 vorrtex 但我必须在不使用任何 mvvm 工具包的情况下执行此操作,这意味着我必须自己编写所有 mvvm。我也觉得你的例子有点混乱。我不知道什么是“Messenger.Default.Register
  • @deckard cain Messenger 是 MVVM Light 工具包中的类。无论如何,我已经添加了如何在没有自定义框架的情况下实现相同功能的代码。
  • @vortex 再次感谢,但我似乎无法确定您在哪里将视图加载到内容中
  • @deckard cain xaml 中有 ContentControl Content="{Binding CurrentView}" 行。并且在视图模型中有属性CurrentView。如果您更改此属性 - 更改将反映在用户界面中。在我的示例中,我将 TextBlock 设置为该属性,但您可以设置任何 UserControl。
  • @vorrtex 感谢您的回复。我会看看我是否可以在我的项目中实现它。如果你愿意,你可以看看这个megaupload.com/?d=G2I0KVR2 这是我正在尝试做的小型 mvvm 项目。 LoadUnloadControl 在应用程序启动时加载到其内容中,我需要通过单击加载将其他控件加载到下部内容控件中,并通过单击卸载将其卸载。但我不知道如何实现..
【解决方案2】:

听起来您可能正在尝试进行某种导航。如果这是真的,请查看Silverlight navigation framework.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-02
    • 1970-01-01
    • 2021-02-17
    • 1970-01-01
    • 2014-04-17
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多