2011-08-15 26 views
0

我剛開始研究WPF和MVVM,我正在考慮我需要開始使用MVVM。如何使用WPF和MVVM做一些簡單的佈局和操作?

我有一個winform應用程序,主面板,在主面板左側有一些按鈕,在主面板的右側是一個區域放置不同的子面板(一次一個面板) ,點擊一個主表格按鈕後,將調用一個子表格的方法。

是否有可能使用MVVM來做這樣的佈局和操作?

+0

我必須在新版本中使用WPF,所以沒有winform了 – markgoo

回答

0

對不起,第一次誤會。我創建了一個小樣本。這裏是XAML代碼:

<Window x:Class="S4SO.ContainerBinding.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="520" Width="425"> 
    <Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="80" /> 
     <RowDefinition Height="400" /> 
    </Grid.RowDefinitions> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="400" /> 
    </Grid.ColumnDefinitions> 
    <ContentControl Content="{Binding ContentContent}" Grid.Row="1" Height="400" Width="400" /> 
    <StackPanel Orientation="Horizontal"> 
     <Button Content="Use button" Command="{Binding UseButton}" /> 
     <Button Content="Use Textbox" Command="{Binding UseTextbox}" /> 
    </StackPanel> 
    </Grid> 
</Window> 

窗口被綁定到視圖模型,爲簡單起見我把MVVMLight爲基礎:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Input; 
using System.Windows.Controls; 
using System.Windows; 
using GalaSoft.MvvmLight.Command; 
using GalaSoft.MvvmLight; 

namespace S4SO.ContainerBinding { 
    public class ViewModel : ViewModelBase { 
    private object _ContentContent; 

    public object ContentContent { 
     get { return _ContentContent; } 
     set { 
     if (_ContentContent.GetType() == value.GetType()) 
      return; 
     _ContentContent = value; 
     RaisePropertyChanged("ContentContent"); 
     } 
    } 

    public ICommand UseButton { get; set; } 

    public void CommandUseButton() { 
     ContentContent = new Button() { 
     Content = "A button", 
     Width = 400, 
     Height = 400, 
     VerticalContentAlignment = VerticalAlignment.Center, 
     HorizontalContentAlignment = HorizontalAlignment.Center 
     }; 
    } 

    public bool CanUseButton() { 
     return !(_ContentContent is Button); 
    } 

    public ICommand UseTextbox { get; set; } 

    public void CommandUseTextbox() { 
     ContentContent = new TextBox() { 
     Text = "Content here", 
     Width = 400, 
     Height = 400, 
     VerticalContentAlignment = VerticalAlignment.Center, 
     HorizontalContentAlignment = HorizontalAlignment.Center 
     }; 
    } 

    public bool CanUseTextbox() { 
     return !(_ContentContent is TextBox); 
    } 

    public ViewModel() { 
     _ContentContent = new Label() { 
     Content = "Please choose content!", 
     Width = 400, 
     Height = 400, 
     HorizontalContentAlignment = HorizontalAlignment.Center, 
     VerticalContentAlignment = VerticalAlignment.Center 
     }; 
     UseButton = new RelayCommand(() => CommandUseButton(),() => CanUseButton()); 
     UseTextbox = new RelayCommand(() => CommandUseTextbox(),() => CanUseTextbox()); 
    } 

    } 
} 

非也生產水平,但它表明一個方向,希望現在更你要求什麼。我使用了簡單的控件,並沒有深入到綁定那些動態創建的控件。通過代碼進行綁定並不像XAML中的綁定語法那樣簡單。如果這是正確的方向,我會保持這一點。

+0

謝謝,但我不得不使用WPF作爲新版本。 – markgoo

+0

謝謝隊友!我會試一試! :p – markgoo

+0

嗨Sascha,我可以加載一個默認的用戶控制在該數據庫的一些數據右側區域?我正在使用Interaction.Triggers,但它不起作用。在那之後,我在那個用戶控件中做了一些操作,然後用戶控件用一些參數加載另一個用戶控件來替換它自己,我應該將事件提升到主視圖然後將它加載到主視圖中?還有左邊區域的按鈕,點擊其中一個後,我需要在右邊的用戶控件中做一些特定的工作,如何在主視圖中調用用戶控件的方法?對不起,格式爲:p – markgoo

1

當然。左側和右側面板都將綁定到單個ViewModel(這是代表當前面板的VM)。左邊的按鈕將調用ViewModel上的操作(可能通過命令)。

當活動虛擬機發生變化時(即右側顯示不同面板時),則左面板的數據上下文會更改爲新虛擬機。

您可能需要某種容器虛擬機來表示整個窗口,其中有幾個子ViewModel表示每個可能的面板在右邊。在任何給定時間,其中只有一個被設置爲活動面板。這有意義嗎?

1

主視圖模型將包含屬性

  • ViewModelBase CurrentPage
  • ICommand ChangePageCommand
  • ObservableCollection<ViewModelBase> AvailablePages

主視圖將包含

  • ContentControl跨顯示AvailablePages
  • 點擊菜單區域的鏈接會調用ChangePage命令到CurrentPage切換到所選AvailablePage屏幕的左側託管CurrentPage

  • 菜單區域。

  • DataTemplates將用於基於什麼正在顯示CurrentPage

ChildViewModel因爲主視圖模型可以訪問所有可用的頁面,如果需要,它可以執行對ChildViewModels方法來顯示ChildViews,和該ChangePageCommand可以從

我寫了這樣的接口,如果你有興趣here的一個例子ChildViewModels被調用,儘管它只能顯示切換CurrentPage,不THR導航爲例ough AvailablePages

+0

謝謝你蕾切爾!我會嘗試一下,:p – markgoo