티스토리 뷰

반응형

이번회에는 목록화면과 상세화면의 전환에 대해서 다루어 보도록 하겠다. 오늘의 목표화면을 먼저 보자


목록화면에 '보기'라는 버튼이 추가가 되었고, '보기'를 클릭하면 상세 화면으로 전환되고 내용이 표시된다. 상세화면은 디자인을 좀더 손을 볼 필요가 있지만...일단 차후에 보는 것으로 정하고 올린다.

 1. 목록 <-> 상세 전환 흐름

BoardListView.xaml : 보기 버튼 클릭 -> BoardListView.xaml.cs : Button_Click 이벤트
(커맨드 엑션이 발생하지 않아서 직접 코딩으로 처리, 아마 실력 부족일듯..^^;;;)
-> BoardListViewModel.cs : SelectChangedOperation(object obj) 실행

* 여기서 BoardListData.CurrentData를 좀전에 그리드에서 선택한 아이템으로 변경
-> BoardList.cs : OnPropertyChanged("CurrentData") 이벤트 발생
-> MainPageViewModel.cs : void BoardListData_PropertyChanged(object sender, PropertyChangedEventArgs e) 실행

* 여기에서 CurrentData가 변경되었을 때 데이터가 존재하는지 여부에 따라서 CurrentViewName을 설정하면 또 프로퍼티 체인지 이벤트가 발생 -> MainPage.xaml.cs에 void MainPageVM_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) 실행

* 그래서 해당 화면으로 변경

2. MainPage.xaml.cs

using System;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Windows;
using System.Windows.Controls;

using SL5_BOARD.Views;
using SL5_BOARD.ViewModels;
using System.ComponentModel.Composition;

using System.Collections.ObjectModel;
using System.Windows.Data;

namespace SL5_BOARD
{
    public partial class MainPage : UserControl
    {
        //메인 페이지 뷰모델 임포트
        [Import(typeof(MainPageViewModel))]
        public MainPageViewModel MainPageVM {get; set;}

        /// <summary>
        /// 가상 프로퍼티 보드메인뷰
        /// </summary>
        public virtual BoardMainView VBoardMainView { get; set; }

        /// <summary>
        /// 가상 프로퍼티 보드리스트뷰
        /// </summary>
        public virtual BoardListView VBoardListView { get; set; }

        /// <summary>
        /// 가상 프로퍼티 회원관리뷰
        /// </summary>
        public virtual MstMemberView VMstMemberView { get; set; }

        /// <summary>
        /// 가상 프로퍼티 보드리스트상세뷰
        /// </summary>
        public virtual BoardListDetailView VBoardListDetailView { get; set; }

        public MainPage()
        {
            InitializeComponent();

            //임포트 초기화 : 이명령은 뷰단에서 한번 실행되면, 그 하위 컴포넌트 들도 차례대로 인스턴스화 된다.
            CompositionInitializer.SatisfyImports(this);

            //메인페이지 뷰모델을 LayoutRoot의 DataContext에 바인딩
            LayoutRoot.DataContext = MainPageVM;

            MainPageVM.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(MainPageVM_PropertyChanged);

            VBoardMainView = new BoardMainView();
            VBoardListView = new BoardListView();
            VMstMemberView = new MstMemberView();
            VBoardListDetailView = new BoardListDetailView();
        }

        /// <summary>
        /// 메인페이지뷰모델 프로퍼티 체인지 이벤트
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void MainPageVM_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "CurrentViewName":
                    switch (MainPageVM.CurrentViewName)
                    {
                        case "BoardMainView":
                            MainPageVM.CurrentView = VBoardMainView;
                            break;
                        case "BoardListView":
                            MainPageVM.CurrentView = VBoardListView;
                            break;
                        case "MstMemberView":
                            MainPageVM.CurrentView = VMstMemberView;
                            break;
                        case "BoardListDetailView":
                            MainPageVM.CurrentView = VBoardListDetailView;
                            break;
                    }
                    break;
                default:
                    break;
            }
       }

    }
}

3. MainPageViewModel.cs 일부

        /// <summary>
        /// 보드리스트 모델 임포트 - 선택된 게시물 변경
        /// </summary>
        BoardList boardListData;
        [Import(typeof(BoardList))]
        public BoardList BoardListData
        {
            get
            {
                return boardListData;
            }
            set
            {
                boardListData = value;
                BoardListData.PropertyChanged += new PropertyChangedEventHandler(BoardListData_PropertyChanged);
            }
        }

        /// <summary>
        /// 보드리스트 데이터 모델 프로퍼티 체인지 이벤트
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void BoardListData_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "CurrentData":
                    if (BoardListData.CurrentData != null)
                    {
                        CurrentViewName = "BoardListDetailView";
                    }
                    else
                    {
                        CurrentViewName = "BoardListView";
                    }
                    break;
            }
        }

4. BoardList.cs 일부

        BOARD_LIST currentData;
        /// <summary>
        /// 현재 선택된 데이터
        /// </summary>
        public BOARD_LIST CurrentData
        {
            get
            {
                return currentData;
            }
            set
            {
                if (currentData != value)
                {
                    currentData = value;
                    OnPropertyChanged("CurrentData");
                }
            }
        }

5. BoardListViewModel.cs 일부

        ICommand selectChanged;
        /// <summary>
        /// 현재 아이템 변경 커맨드
        /// </summary>
        public ICommand SelectChangedCommand
        {
            get
            {
                if (selectChanged == null)
                {
                    selectChanged = new ActionCommand(obj => SelectChangedOperation(obj));
                }
                return selectChanged;
            }
        }
        /// <summary>
        /// 커맨드 엑션이 발생하지 않아 이곳을 직접 호출
        /// </summary>
        /// <param name="obj"></param>
        public void SelectChangedOperation(object obj)
        {
            if (obj != null && obj is BOARD_LIST)
            {
                BoardListData.CurrentData = obj as BOARD_LIST;
            }
        }

        ICommand listCommand;
        /// <summary>
        /// 목록으로 커맨드
        /// </summary>
        public ICommand ListCommand
        {
            get
            {
                if (listCommand == null)
                {
                    listCommand = new ActionCommand(() =>
                    {
                        BoardListData.CurrentData = null;
                    });
                }
                return listCommand;
            }
        }


6. BoardListView.xaml.cs

using System.ComponentModel.Composition;
using System.Windows;
using System.Windows.Controls;
using SL5_BOARD.ViewModels;

namespace SL5_BOARD.Views
{
    public partial class BoardListView : UserControl
    {
        [Import(typeof(BoardListViewModel))]
        public BoardListViewModel BoardListVM { get; set; }

        public BoardListView()
        {
            InitializeComponent();

            CompositionInitializer.SatisfyImports(this);

            this.DataContext = BoardListVM;

        }

        /// <summary>
        /// 보기 버튼 이벤트 - 커맨드 엑션이 발생하지 않아서 직접 코딩
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            if (this.grdBoardList.SelectedItem != null)
            {
                BoardListVM.SelectChangedOperation(this.grdBoardList.SelectedItem);
            }
        }
    }
}

7. BoardListView.xaml 일부

  <sdk:DataGrid AutoGenerateColumns="False" Grid.Row="2" IsReadOnly="True"
   x:Name="grdBoardList"
   ColumnWidth="*" DataContext="{Binding BoardListData.ConditionData}" ItemsSource="{Binding}">
   <sdk:DataGrid.Columns>
                <sdk:DataGridTextColumn x:Name="bOARD_LIST_IDXColumn" Binding="{Binding BOARD_LIST_IDX, Mode=OneWay}" Header="번호" Width="50" />
    <sdk:DataGridTextColumn x:Name="lIST_TITLEColumn" Binding="{Binding LIST_TITLE}" Header="제목" CanUserSort="True" />
    <sdk:DataGridCheckBoxColumn x:Name="lIST_ATTACH_YNColumn" Binding="{Binding LIST_ATTACH_YN}" Header="첨부" Width="50" />
    <sdk:DataGridTextColumn x:Name="rEG_IDXColumn" Binding="{Binding MstMember.MEMBER_NAME}" Header="작성자"  Width="70"/>
    <sdk:DataGridTemplateColumn x:Name="rEG_DTColumn" Header="작성일" Width="70">
     <sdk:DataGridTemplateColumn.CellTemplate>
      <DataTemplate>
       <TextBlock Text="{Binding REG_DT, StringFormat=yyyy.MM.dd}" VerticalAlignment="Center" />
      </DataTemplate>
     </sdk:DataGridTemplateColumn.CellTemplate>
    </sdk:DataGridTemplateColumn>
    <sdk:DataGridTextColumn x:Name="lIST_VIEW_COUNTColumn" Binding="{Binding LIST_VIEW_COUNT, StringFormat=N0}" Header="조회"  Width="50"/>
                <sdk:DataGridTemplateColumn x:Name="btnDetail" Width="60" Header="상세">
     <sdk:DataGridTemplateColumn.CellTemplate>
      <DataTemplate>
       <Button Content="보기" Click="Button_Click">
        <i:Interaction.Triggers>
         <i:EventTrigger EventName="Click">
                                        <i:InvokeCommandAction Command="{Binding Path=DataContext.SelectChangedCommand, ElementName=LayoutRoot_BoardList}"
                                                                CommandParameter="{Binding SelectedItem, ElementName=grdBoardList}"/>
         </i:EventTrigger>
        </i:Interaction.Triggers>
       </Button>
      </DataTemplate>
     </sdk:DataGridTemplateColumn.CellTemplate>
    </sdk:DataGridTemplateColumn>

            </sdk:DataGrid.Columns>
  </sdk:DataGrid>

8. BoardListDetailView.xaml

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:SL5_BOARD_ViewModels="clr-namespace:SL5_BOARD.ViewModels" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" x:Class="SL5_BOARD.Views.BoardListDetailView"
    mc:Ignorable="d"
    d:DesignHeight="500" d:DesignWidth="600">
    <d:DesignProperties.DataContext>
        <SL5_BOARD_ViewModels:BoardListViewModel/>
    </d:DesignProperties.DataContext>
   
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
         <RowDefinition Height="38"/>
         <RowDefinition Height="35"/>
         <RowDefinition Height="30"/>
         <RowDefinition Height="86"/>
         <RowDefinition />
        </Grid.RowDefinitions>

        <!--메인 타이틀-->
        <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="게시물 상세" FontSize="14.667" FontWeight="Bold" Foreground="{StaticResource ForeColor_Blues}" Margin="8,8,0,8" d:LayoutOverrides="Height"/>
        <!--Line-->
        <Path Data="M0,30 L400,30" Fill="#FF5181B9" Height="3" Margin="0" Stretch="Fill" Stroke="#FF5181B9" UseLayoutRounding="False" VerticalAlignment="Bottom" StrokeLineJoin="Bevel" StrokeThickness="3" d:LayoutOverrides="GridBox"/>
        <TextBox x:Name="txtTitle" Grid.Row="1" TextWrapping="Wrap" FontSize="13.333" Text="{Binding BoardListData.CurrentData.LIST_TITLE, Mode=TwoWay}" FontWeight="Bold" HorizontalAlignment="Left" Style="{StaticResource NormalTextBoxStyle}" Margin="8,4,0,3" IsReadOnly="True"/>
        <!--조회 버튼-->
        <Button x:Name="btnEdit" Content="수정" HorizontalAlignment="Right" Margin="0,6,156,7" Width="70" Grid.Row="1" Height="22"/>
        <Button Content="삭제" Height="22" HorizontalAlignment="Right" Margin="0,6,82,7" x:Name="btnDelete" Width="70" Grid.Row="1" />
        <Button Content="목록" Height="22" HorizontalAlignment="Right" Margin="0,6,8,7" x:Name="btnList" Width="70" Grid.Row="1" >
         <i:Interaction.Triggers>
          <i:EventTrigger EventName="Click">
           <i:InvokeCommandAction Command="{Binding ListCommand, Mode=OneWay}"/>
          </i:EventTrigger>
         </i:Interaction.Triggers>
        </Button>
        <!--Line-->
        <Path Data="M0,30 L400,30" Fill="{StaticResource ForeColor_Kakis}" Stretch="Fill" Stroke="{StaticResource ForeColor_Kakis}" UseLayoutRounding="False" StrokeLineJoin="Bevel" StrokeThickness="3" Grid.Row="1" Height="3" VerticalAlignment="Bottom" Margin="0,0,0,-1" d:LayoutOverrides="GridBox"/>
        <StackPanel Margin="8,5,8,4" Orientation="Horizontal" Grid.Row="2">
         <TextBlock x:Name="txtRegUser" TextWrapping="Wrap" FontSize="13.333" Text="{Binding BoardListData.CurrentData.MstMember.NICK_NAME}" FontWeight="Bold"/>
         <TextBlock x:Name="txtGrade" Margin="0" TextWrapping="Wrap" FontSize="10.667" Text="{Binding BoardListData.CurrentData.MstMember.MEMBER_GRADE}" VerticalAlignment="Center"/>

        </StackPanel>
 
  <!--커맨드패널-->
  <!----생략------> 
 
        <Border Grid.Row="4" BorderThickness="4" BorderBrush="{StaticResource ForeColor_Kakis}" CornerRadius="10" >
            <RichTextBox x:Name="rtb" VerticalScrollBarVisibility="Auto"
         BorderBrush="{x:Null}" Margin="8,10,10,8" TextWrapping="Wrap"
                         SelectionChanged="rtb_SelectionChanged" IsReadOnly="True">
                <Paragraph>
                    <Run Text="{Binding BoardListData.CurrentData.LIST_CONTENT, Mode=TwoWay}"/>
                </Paragraph>
            </RichTextBox>

        </Border>

    </Grid>
</UserControl>

9. 보기 버튼을 눌렀을 때..
 SelectChangedCommand 커맨드가 실행이 앙대는 이유를 찾다가..너무 오래 걸릴 것 같아서 2가지 소스를 같이 올린다. 소스보고 따라하기를 하다가 커맨드가 동작이 된다면 꼭 알려주기를..흐흐흐 언제나 궁금한 내용이나 의견이 있으면 리플로 남겨주기 바란다.
이제는 비가 그만 왔으면 좋겠다....

참고자료

Silverlight RichTextBox Lab
http://msdn.microsoft.com/en-us/gg315161

반응형
댓글