2012-04-03 2 views
12

MainViewMamel에 대한 바인딩 인 MainView.xaml이 있습니다.Caliburn.Micro를 사용하여 MainView의 UserControls를 ViewModels에 바인딩합니다.

내가 해보고 싶었던 것은 내 기본 양식에있는 많은 컨트롤을 UserControls로 분할하는 것이 었습니다.

이제 UserViewrols를 MainView와 함께 Views 폴더에 넣고 LeftSideControlView.xaml 및 RightSideControlView.xaml이라고 명명했습니다. 해당 ViewModels는

나는 성공적으로 MAINVIEW에 추가 된 UserControls 추가 등 LeftSideControlViewModel라는 ViewModels 폴더에 있습니다

<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition /> 
     <ColumnDefinition /> 
    </Grid.ColumnDefinitions> 
    <UserControls:LeftSideControlView cal:Bind.Model="{Binding}" /> 
    <UserControls:RightSideControlView cal:Bind.Model="{Binding}" 
            Grid.Column="1" /> 
</Grid> 

가 디자이너에서 올바르게 표시됩니다. 다음은 XAML에서 그들 중 하나입니다 :

<UserControl x:Class="TwitterCaliburnWPF.Library.Views.LeftSideControlView" 
     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" 
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="300"> 
<Grid> 
    <StackPanel> 
     <Label x:Name="Text" FontSize="25" HorizontalAlignment="Center" Margin="5"/> 
     <TextBox x:Name="TextBox1" 
       Width="200" 
       HorizontalAlignment="Center" FontSize="25" Margin="5" /> 
     <Button Width="200" Height="50" Content="Button!" Margin="20" /> 
    </StackPanel> 
</Grid> 

내가 Caliburn가 Castle.Windsor를 사용하기위한 AppBootstrapper 내부 viewmodels과 인터페이스를 추가했다. 여기에 MainViewModel가 있고 난이 아무것도에 MainViewModel에 특별히 없었다 시도하기 전에 나는, 내가 Caliburn.Micro의 documention에서 읽은 내용 오프거야

using Screen = Caliburn.Micro.Screen; 

namespace TwitterCaliburnWPF.Library.ViewModels 
{ 
    public class LeftSideControlViewModel : Screen, ILeftSideControlViewModel 
    { 
     private string _text = "Hello from the Left side!"; 
     private string _textBox1 = "Enter Text Here"; 

     public string Text 
     { 
      get { return _text; } 
     } 

     public string TextBox1 
     { 
      get { return _textBox1; } 
     } 
    } 
} 

: 여기

public class ApplicationContainer : WindsorContainer 
{ 
    public ApplicationContainer() 
    { 
    // Register all dependencies here 
    Register(
     Component.For<IWindowManager>().ImplementedBy<WindowManager>().LifeStyle.Is(LifestyleType.Singleton), 
     Component.For<IEventAggregator>().ImplementedBy<EventAggregator>().LifeStyle.Is(LifestyleType.Singleton), 
     Component.For<ILeftSideControlViewModel>().ImplementedBy<LeftSideControlViewModel>(), 
     Component.For<IRightSideControlViewModel>().ImplementedBy<RightSideControlViewModel>() 
     ); 

    RegisterViewModels(); 
    } 

    private void RegisterViewModels() 
    { 
    Register(AllTypes.FromAssembly(GetType().Assembly) 
        .Where(x => x.Name.EndsWith("ViewModel")) 
        .Configure(x => x.LifeStyle.Is(LifestyleType.Transient))); 
    } 

는 LeftSideControlViewModel 클래스의 이 두 컨트롤을로드하거나이 두 컨트롤을 표시하도록 지시하십시오.

여전히 앱이 실행 중일 때 값은 해당 뷰 모델의 usercontrol에 바인딩되지 않습니다.

namespace TwitterCaliburnWPF.Library.ViewModels 
{ 
    public class MainViewModel : Conductor<IScreen> 
    { 
     public MainViewModel() 
     { 
     ShowLeftControl(); 
     ShowRightControl(); 
     } 

     private void ShowRightControl() 
     { 
     ActivateItem(new RightSideControlViewModel()); 
     } 

     private void ShowLeftControl() 
     { 
     ActivateItem(new LeftSideControlViewModel()); 
     } 

     public string TextToDisplay 
     { 
     get { return "Coming from the ViewModel!"; } 
     } 
    } 
} 

답변

22

여기서 Conductor을 사용할 필요는 없습니다. 이것은 기본적으로 탐색 시나리오에 사용됩니다. MainViewModel에 RightSide라고하는 RightSideControlViewModel 중 하나와 LeftSide라고하는 LeftSideControlViewModel 중 하나를 두 개의 공개 속성으로 만드십시오. 그런 다음 MainControl에서 직접 UserControl을 인스턴스화하는 대신 x:Name="LeftSide"으로 두 개의 ContentControls을 만들고 두 번째로 x:name="RightSide"을 만듭니다. 이것은 뷰 모델 - 첫 번째 달성 방법입니다. 먼저보기를 원할 경우 MainView에 사용자 정의 컨트롤을 유지하고 Bind.Model을 새로 만든 속성 (예 : Bind.Model="{Binding LeftSide}")을 변경하도록 변경합니다.

기본적으로 사용자 정의 방법 .... 바인딩은 어느 정도 올바른 오브젝트를 가리키고 있지 않습니다. 거기에 지휘자가 있는데, 이것을 수행 할 필요가 없습니다. 일종의 네비게이션 아키텍처를 사용하려는 경우 계속 유지해야 할 수 있습니다. 지휘자에서 ActivateItem을 호출하면 기본적으로 ActiveItem 속성이 변경된다는 것을 기억하십시오. 한 번에 하나의 모델 만 활성화됩니다. 위의 경우 두 항목을 모두 활성화하지만 두 번째 항목 만 활성 상태로 유지합니다. 또한, 귀하의 관점에서 아무것도 ActiveItem에 바인딩됩니다.

나는 이것이 의미가 있기를 바랍니다.

관련 문제