첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
------------------------------------------------------------------------------------------------------------------------------------------------------
728x90
728x170

■ 데이터 바인딩을 사용하는 기본적인 방법을 보여준다.

TestProject.zip
0.02MB

▶ ProductCategory.cs

namespace TestProject
{
    /// <summary>
    /// 제품 카테고리
    /// </summary>
    public enum ProductCategory
    {
        /// <summary>
        /// 책
        /// </summary>
        Books,

        /// <summary>
        /// 컴퓨터
        /// </summary>
        Computers,

        /// <summary>
        /// DVD
        /// </summary>
        DvDs,

        /// <summary>
        /// 전자 제품
        /// </summary>
        Electronics,

        /// <summary>
        /// 가정용품
        /// </summary>
        Home,

        /// <summary>
        /// 스포츠
        /// </summary>
        Sports
    }
}

 

▶ SpecialFeatures.cs

namespace TestProject
{
    /// <summary>
    /// 특수 기능
    /// </summary>
    public enum SpecialFeatures
    {
        /// <summary>
        /// 해당 무
        /// </summary>
        None,

        /// <summary>
        /// 색상
        /// </summary>
        Color,

        /// <summary>
        /// 하이라이트
        /// </summary>
        Highlight
    }
}

 

▶ User.cs

using System;

namespace TestProject
{
    /// <summary>
    /// 사용자
    /// </summary>
    public class User
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 성명 - Name

        /// <summary>
        /// 성명
        /// </summary>
        public string Name { get; }

        #endregion
        #region 등급 - Rating

        /// <summary>
        /// 등급
        /// </summary>
        public int Rating { get; set; }

        #endregion
        #region 가입일 - MemberSince

        /// <summary>
        /// 가입일
        /// </summary>
        public DateTime MemberSince { get; }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - User(name, rating, memberSince)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="name">성명</param>
        /// <param name="rating">등급</param>
        /// <param name="memberSince">가입일</param>
        public User(string name, int rating, DateTime memberSince)
        {
            Name        = name;
            Rating      = rating;
            MemberSince = memberSince;
        }

        #endregion
    }
}

 

▶ Bid.cs

namespace TestProject
{
    /// <summary>
    /// 입찰
    /// </summary>
    public class Bid
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 금액 - Amount

        /// <summary>
        /// 금액
        /// </summary>
        public int Amount { get; }

        #endregion
        #region 입찰자 - Bidder

        /// <summary>
        /// 입찰자
        /// </summary>
        public User Bidder { get; }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - Bid(amount, bidder)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="amount">금액</param>
        /// <param name="bidder">입찰자</param>
        public Bid(int amount, User bidder)
        {
            Amount = amount;
            Bidder = bidder;
        }

        #endregion
    }
}

 

▶ AuctionItem.cs

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace TestProject
{
    /// <summary>
    /// 경매 항목
    /// </summary>
    public class AuctionItem : INotifyPropertyChanged
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Event
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 속성 변경시 - PropertyChanged

        /// <summary>
        /// 속성 변경시
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 입찰 컬렉션
        /// </summary>
        private readonly ObservableCollection<Bid> bidCollection;

        /// <summary>
        /// 제품 카테고리
        /// </summary>
        private ProductCategory category;

        /// <summary>
        /// 설명
        /// </summary>
        private string description;

        /// <summary>
        /// 특수 기능
        /// </summary>
        private SpecialFeatures specialFeatures;

        /// <summary>
        /// 시작일
        /// </summary>
        private DateTime startDate;

        /// <summary>
        /// 시작가
        /// </summary>
        private int startPrice;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 설명 - Description

        /// <summary>
        /// 설명
        /// </summary>
        public string Description
        {
            get
            {
                return this.description;
            }
            set
            {

                if(string.IsNullOrEmpty(value))
                {
                    throw new ArgumentException("Item description should be added");
                }

                this.description = value;

                FirePropertyChangedEvent("Description");
            }
        }

        #endregion
        #region 시작가 - StartPrice

        /// <summary>
        /// 시작가
        /// </summary>
        public int StartPrice
        {
            get
            {
                return this.startPrice;
            }
            set
            {
                if(value < 0)
                {
                    throw new ArgumentException("Price must be positive. Provide a positive price");
                }

                this.startPrice = value;

                FirePropertyChangedEvent("StartPrice");
                FirePropertyChangedEvent("CurrentPrice");
            }
        }

        #endregion
        #region 시작일 - StartDate

        /// <summary>
        /// 시작일
        /// </summary>
        public DateTime StartDate
        {
            get
            {
                return this.startDate;
            }
            set
            {
                this.startDate = value;

                FirePropertyChangedEvent("StartDate");
            }
        }

        #endregion
        #region 제품 카테고리 - Category

        /// <summary>
        /// 제품 카테고리
        /// </summary>
        public ProductCategory Category
        {
            get
            {
                return this.category;
            }
            set
            {
                this.category = value;

                FirePropertyChangedEvent("Category");
            }
        }

        #endregion
        #region 소유자 - Owner

        /// <summary>
        /// 소유자
        /// </summary>
        public User Owner { get; }

        #endregion
        #region 특수 기능 - SpecialFeatures

        /// <summary>
        /// 특수 기능
        /// </summary>
        public SpecialFeatures SpecialFeatures
        {
            get
            {
                return this.specialFeatures;
            }
            set
            {
                this.specialFeatures = value;

                FirePropertyChangedEvent("SpecialFeatures");
            }
        }

        #endregion
        #region 입찰 컬렉션 - BidCollection

        /// <summary>
        /// 입찰 컬렉션
        /// </summary>
        public ReadOnlyObservableCollection<Bid> BidCollection => new ReadOnlyObservableCollection<Bid>(this.bidCollection);

        #endregion
        #region 현재가 - CurrentPrice

        /// <summary>
        /// 현재가
        /// </summary>
        public int CurrentPrice
        {
            get
            {
                int price;

                if(this.bidCollection.Count > 0)
                {
                    Bid lastBid = this.bidCollection[this.bidCollection.Count - 1];

                    price = lastBid.Amount;
                }
                else
                {
                    price = this.startPrice;
                }

                return price;
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - AuctionItem(description, category, startPrice, startDate, owner, specialFeatures)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="description">설명</param>
        /// <param name="category">제품 카테고리</param>
        /// <param name="startPrice">시작가</param>
        /// <param name="startDate">시작일</param>
        /// <param name="owner">소유자</param>
        /// <param name="specialFeatures">특수 기능</param>
        public AuctionItem(string description, ProductCategory category, int startPrice, DateTime startDate, User owner, SpecialFeatures specialFeatures)
        {
            this.description     = description;
            this.category        = category;
            this.startPrice      = startPrice;
            this.startDate       = startDate;
            this.specialFeatures = specialFeatures;
            this.bidCollection   = new ObservableCollection<Bid>();

            Owner = owner;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 입찰 추가하기 - AddBid(bid)

        /// <summary>
        /// 입찰 추가하기
        /// </summary>
        /// <param name="bid">입찰</param>
        public void AddBid(Bid bid)
        {
            this.bidCollection.Add(bid);

            FirePropertyChangedEvent("CurrentPrice");
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

        #region 속성 변경시 이벤트 발생시키기 - FirePropertyChangedEvent(propertyName)

        /// <summary>
        /// 속성 변경시 이벤트 발생시키기
        /// </summary>
        /// <param name="propertyName">속성명</param>
        protected void FirePropertyChangedEvent(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }
}

 

▶ DateConverter.cs

using System;
using System.Globalization;
using System.Windows.Data;

namespace TestProject
{
    /// <summary>
    /// 날짜 변환자
    /// </summary>
    [ValueConversion(typeof (DateTime), typeof (string))]
    public class DateConverter : IValueConverter
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 변환하기 - Convert(sourceValue, targetType, parameter, cultureInfo)

        /// <summary>
        /// 변환하기
        /// </summary>
        /// <param name="sourceValue">소스 값</param>
        /// <param name="targetType">타겟 타입</param>
        /// <param name="parameter">매개 변수</param>
        /// <param name="cultureInfo">문화 정보</param>
        /// <returns>변환 값</returns>
        public object Convert(object sourceValue, Type targetType, object parameter, CultureInfo cultureInfo)
        {
            DateTime date = (DateTime)sourceValue;

            return date.ToShortDateString();
        }

        #endregion
        #region 역변환하기 - ConvertBack(sourceValue, targetType, parameter, cultureInfo)

        /// <summary>
        /// 역변환하기
        /// </summary>
        /// <param name="sourceValue">소스 값</param>
        /// <param name="targetType">타겟 타입</param>
        /// <param name="parameter">매개 변수</param>
        /// <param name="cultureInfo">문화 정보</param>
        /// <returns>역변환 값</returns>
        public object ConvertBack(object sourceValue, Type targetType, object parameter, CultureInfo cultureInfo)
        {
            string source = sourceValue.ToString();

            DateTime tartgetDate;

            if(DateTime.TryParse(source, out tartgetDate))
            {
                return tartgetDate;
            }

            return sourceValue;
        }

        #endregion
    }
}

 

▶ SpecialFeaturesConverter.cs

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace TestProject
{
    /// <summary>
    /// 특수 기능 변환자
    /// </summary>
    public class SpecialFeaturesConverter : IMultiValueConverter
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 변환하기 - Convert(sourceValueArray, targetType, parameter, cultureInfo)

        /// <summary>
        /// 변환하기
        /// </summary>
        /// <param name="sourceValueArray">소그 값 배열</param>
        /// <param name="targetType">타겟 타입</param>
        /// <param name="parameter">매개 변수</param>
        /// <param name="cultureInfo">문화 정보</param>
        /// <returns>변환 값</returns>
        public object Convert(object[] sourceValueArray, Type targetType, object parameter, CultureInfo cultureInfo)
        {
            if(sourceValueArray == null || sourceValueArray.Length < 2)
            {
                return false;
            }

            if(sourceValueArray[0] == DependencyProperty.UnsetValue)
            {
                return false;
            }

            if(sourceValueArray[1] == DependencyProperty.UnsetValue)
            {
                return false;
            }

            int      rating = (int)sourceValueArray[0];
            DateTime date   = (DateTime)sourceValueArray[1];

            if((rating >= 10) && (date.Date < (DateTime.Now.Date - new TimeSpan(365, 0, 0, 0))))
            {
                return true;
            }

            return false;
        }

        #endregion
        #region 역변환하기 - ConvertBack(sourceValue, targetTypeArray, parameter, cultureInfo)

        /// <summary>
        /// 역변환하기
        /// </summary>
        /// <param name="sourceValue">소스 값</param>
        /// <param name="targetTypeArray">타겟 타입 배열</param>
        /// <param name="parameter">매개 변수</param>
        /// <param name="cultureInfo">문화 정보</param>
        /// <returns>역변환 값</returns>
        public object[] ConvertBack(object sourceValue, Type[] targetTypeArray, object parameter, CultureInfo cultureInfo) => new[] { Binding.DoNothing, Binding.DoNothing };

        #endregion
    }
}

 

▶ Style.xaml

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style x:Key="TitleTextBlockStyleKey" TargetType="TextBlock">
        <Setter Property="Foreground" Value="DodgerBlue" />
        <Setter Property="FontSize"   Value="18"         />
        <Setter Property="FontWeight" Value="Bold"       />
    </Style>
    <Style x:Key="GroupHeaderTextBlockStyleKey" TargetType="TextBlock">
        <Setter Property="Foreground" Value="Navy" />
        <Setter Property="FontSize"   Value="12"   />
        <Setter Property="FontWeight" Value="Bold" />
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="true" >
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
    <Style x:Key="SmallTitleTextBlockStyleKey" TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Right"  />
        <Setter Property="VerticalAlignment"   Value="Center" />
        <Setter Property="Foreground"          Value="Black"  />
        <Setter Property="FontWeight"          Value="Bold"   />
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="true" >
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
    <Style x:Key="TextTextBlockStyleKey" TargetType="TextBlock">
        <Setter Property="Foreground" Value="Black" />
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="true" >
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
    <Style x:Key="TextTextBoxStyleKey" TargetType="TextBox">
        <Setter Property="Width"      Value="400"     />
        <Setter Property="MaxLength"  Value="40"      />
        <Setter Property="Foreground" Value="#333333" />
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="true" >
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
            </DataTrigger>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
            </Trigger>
        </Style.Triggers>
    </Style>
    <Style x:Key="ComboBoxItemStyleKey" TargetType="ComboBoxItem">
        <Setter Property="Foreground" Value="#333333" />
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="true" >
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
            </DataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}"                   Value="true" />
                    <Condition Binding="{Binding Path=IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true" />
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="TextBlock.Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}"                     Value="true" />
                    <Condition Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Self}}"    Value="true" />
                    <Condition Binding="{Binding Path=IsHighlighted, RelativeSource={RelativeSource Self}}" Value="true" />
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="TextBlock.Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}"                         Value="true" />
                    <Condition Binding="{Binding Path=IsKeyboardFocused, RelativeSource={RelativeSource Self}}" Value="true" />
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="TextBlock.Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>
    <Style x:Key="ComboBoxStyleKey" TargetType="ComboBox">
        <Setter Property="Foreground" Value="#333333" />
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="true">
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
            </DataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Path=(SystemParameters.HighContrast)}"                                 Value="true" />
                    <Condition Binding="{Binding Path=IsSelectionBoxHighlighted, RelativeSource={RelativeSource Self}}" Value="True" />
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="TextBlock.Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>
    <Style x:Key="AuctionItemBorderStyleKey" TargetType="Border">
        <Setter Property="Margin"          Value="3"     />
        <Setter Property="Width"           Value="500"   />
        <Setter Property="BorderThickness" Value="1"     />
        <Setter Property="BorderBrush"     Value="Black" />
        <Setter Property="Padding"         Value="7"     />
    </Style>
    <Style x:Key="BorderStyleKey" TargetType="Border">
        <Setter Property="BorderThickness" Value="0 0 0 2" />
        <Setter Property="BorderBrush"     Value="Black"   />
        <Setter Property="Padding"         Value="5"       />
    </Style>
    <Style x:Key="PolygonStyleKey" TargetType="Polygon">
        <Setter Property="Width"           Value="20"     />
        <Setter Property="Height"          Value="20"     />
        <Setter Property="StrokeThickness" Value="1"      />
        <Setter Property="Stroke"          Value="Black"  />
        <Setter Property="StrokeLineJoin"  Value="Round"  />
        <Setter Property="Fill"            Value="Yellow" />
        <Setter Property="Stretch"         Value="Fill"   />
        <Setter Property="Visibility"      Value="Hidden" />
    </Style>
    <Style x:Key="CheckBoxStyleKey" TargetType="{x:Type CheckBox}">
        <Setter Property="Foreground" Value="#333333" />
        <Setter Property="FontWeight" Value="Bold"    />
    </Style>
    <Style TargetType="{x:Type ListBoxItem}">
        <Style.Triggers>
            <Trigger Property="Selector.IsSelected" Value="True">
                <Setter Property="Background" Value="Moccasin" />
            </Trigger>
        </Style.Triggers>
    </Style>
</ResourceDictionary>

 

▶ MainApplication.xaml

<Application x:Class="TestProject.MainApplication"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestProject"
    StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/TestProject;component/Style.xaml" />
            </ResourceDictionary.MergedDictionaries>
            <local:DateConverter x:Key="DateConverterKey" />
            <DataTemplate DataType="{x:Type local:AuctionItem}" >
                <Border Name="border"
                    Style="{StaticResource AuctionItemBorderStyleKey}">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition />
                            <RowDefinition />
                            <RowDefinition />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="20"  />
                            <ColumnDefinition Width="100" />
                            <ColumnDefinition Width="*"   />
                        </Grid.ColumnDefinitions>
                        <Polygon Name="starPolygon" Grid.Row="0" Grid.Column="0" Grid.RowSpan="4"
                            Style="{StaticResource PolygonStyleKey}"
                            Points="9 2 11 7 17 7 12 10 14 15 9 12 4 15 6 10 1 7 7 7" />
                        <TextBlock Name="descriptionTitleTextBlock" Grid.Row="0" Grid.Column="1"
                            Style="{StaticResource SmallTitleTextBlockStyleKey}"
                            Margin="0 0 10 0">
                            설명 :
                        </TextBlock>
                        <TextBlock Name="descriptionTextBlock" Grid.Row="0" Grid.Column="2"
                            Style="{StaticResource TextTextBlockStyleKey}"
                            Text="{Binding Path=Description}" />
                        <TextBlock Name="currentPriceTitleTextBlock" Grid.Row="1" Grid.Column="1"
                            Style="{StaticResource SmallTitleTextBlockStyleKey}"
                            Margin="0 0 10 0">
                            현재가 :
                        </TextBlock>
                        <StackPanel Grid.Row="1" Grid.Column="2"
                            Orientation="Horizontal">
                            <TextBlock Name="dollarTextBlock"
                                Style="{StaticResource TextTextBlockStyleKey}"
                                Text="$" />
                            <TextBlock Name="currentPriceTextBlock"
                                Style="{StaticResource TextTextBlockStyleKey}"
                                Text="{Binding Path=CurrentPrice}" />
                        </StackPanel>
                    </Grid>
                </Border>
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding Path=SpecialFeatures}" >
                        <DataTrigger.Value>
                            <local:SpecialFeatures>Color</local:SpecialFeatures>
                        </DataTrigger.Value>
                        <DataTrigger.Setters>
                            <Setter
                                TargetName="border"
                                Property="BorderBrush"
                                Value="DodgerBlue" />
                            <Setter
                                TargetName="descriptionTitleTextBlock"
                                Property="Foreground"
                                Value="Navy" />
                            <Setter
                                TargetName="currentPriceTitleTextBlock"
                                Property="Foreground"
                                Value="Navy" />
                            <Setter
                                TargetName="border"
                                Property="BorderThickness"
                                Value="3" />
                            <Setter
                                TargetName="border"
                                Property="Padding"
                                Value="5" />
                        </DataTrigger.Setters>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=SpecialFeatures}">
                        <DataTrigger.Value>
                            <local:SpecialFeatures>Highlight</local:SpecialFeatures>
                        </DataTrigger.Value>
                        <Setter
                            TargetName="border"
                            Property="BorderBrush"
                            Value="Orange" />
                        <Setter
                            TargetName="descriptionTitleTextBlock"
                            Property="Foreground"
                            Value="Navy" />
                        <Setter
                            TargetName="currentPriceTitleTextBlock"
                            Property="Foreground"
                            Value="Navy" />
                        <Setter
                            TargetName="starPolygon"
                            Property="Visibility"
                            Value="Visible" />
                        <Setter
                            TargetName="border"
                            Property="BorderThickness"
                            Value="3" />
                        <Setter
                            TargetName="border"
                            Property="Padding"
                            Value="5" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Path=(SystemParameters.HighContrast)}" Value="true" >
                        <Setter
                            TargetName="descriptionTitleTextBlock"
                            Property="TextBlock.Foreground"
                            Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
                        <Setter
                            TargetName="currentPriceTitleTextBlock"
                            Property="TextBlock.Foreground"
                            Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
                    </DataTrigger>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition
                                Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=IsSelected}"
                                Value="True" />
                            <Condition
                                Binding="{Binding Path=(SystemParameters.HighContrast)}"
                                Value="True" />
                        </MultiDataTrigger.Conditions>
                        <MultiDataTrigger.Setters>
                            <Setter
                                TargetName="descriptionTitleTextBlock"
                                Property="TextBlock.Foreground"
                                Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
                            <Setter
                                TargetName="descriptionTextBlock"
                                Property="TextBlock.Foreground"
                                Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
                            <Setter
                                TargetName="currentPriceTitleTextBlock"
                                Property="TextBlock.Foreground"
                                Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
                            <Setter
                                TargetName="dollarTextBlock"
                                Property="TextBlock.Foreground"
                                Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
                            <Setter
                                TargetName="currentPriceTextBlock"
                                Property="TextBlock.Foreground"
                                Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
                        </MultiDataTrigger.Setters>
                    </MultiDataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
            <DataTemplate x:Key="DetailsProductListingTemplateKey">
                <Grid Margin="5 5 5 10">
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="120" />
                        <ColumnDefinition Width="*"   />
                    </Grid.ColumnDefinitions>
                    <TextBlock Name="descriptionTitleTextBlock" Grid.Row="0" Grid.Column="0"
                        Style="{StaticResource SmallTitleTextBlockStyleKey}"
                        Margin="0 0 10 0">
                        설명 :
                    </TextBlock>
                    <TextBlock Name="descriptionTextBlock" Grid.Row="0" Grid.Column="1"
                        Style="{StaticResource TextTextBlockStyleKey}"
                        Text="{Binding Path=Description}" />
                    <TextBlock Name="startPriceTitleTextBlock" Grid.Row="1" Grid.Column="0"
                        Style="{StaticResource SmallTitleTextBlockStyleKey}"
                        Margin="0 0 10 0">
                        시작가 :
                    </TextBlock>
                    <StackPanel Grid.Row="1" Grid.Column="1"
                        Orientation="Horizontal">
                        <TextBlock
                            Style="{StaticResource TextTextBlockStyleKey}"
                            Text="$" />
                        <TextBlock Name="startPriceTextBlock"
                            Style="{StaticResource TextTextBlockStyleKey}"
                            Text="{Binding Path=StartPrice}" />
                    </StackPanel>
                    <TextBlock Name="startDateTitleTextBlock" Grid.Row="2" Grid.Column="0"
                        Margin="0 0 10 0"
                        Style="{StaticResource SmallTitleTextBlockStyleKey}">
                        시작일 :
                    </TextBlock>
                    <TextBlock Name="StartDateTextBlock" Grid.Row="2" Grid.Column="1"
                        Style="{StaticResource TextTextBlockStyleKey}"
                        Text="{Binding Path=StartDate, Converter={StaticResource DateConverterKey}}" />
                    <TextBlock Name="categoryTitleTextBlock" Grid.Row="3" Grid.Column="0"
                        Margin="0 0 10 0"
                        Style="{StaticResource SmallTitleTextBlockStyleKey}">
                        카테고리 :
                    </TextBlock>
                    <TextBlock Name="categoryTextBlock" Grid.Row="3" Grid.Column="1"
                        Style="{StaticResource TextTextBlockStyleKey}"
                        Text="{Binding Path=Category}" />
                    <TextBlock Name="ownerNameTitleTextBlock" Grid.Row="4" Grid.Column="0"
                        Margin="0 0 10 0"
                        Style="{StaticResource SmallTitleTextBlockStyleKey}">
                        소유자명 :
                    </TextBlock>
                    <TextBlock Name="ownerNameTextBlock" Grid.Row="4" Grid.Column="1"
                        Style="{StaticResource TextTextBlockStyleKey}"
                        Text="{Binding Path=Owner.Name}" />
                    <TextBlock Name="ownerRatingTitleTextBlock" Grid.Row="5" Grid.Column="0"
                        Style="{StaticResource SmallTitleTextBlockStyleKey}"
                        Margin="0 0 10 0">
                        소유자 등급 :
                    </TextBlock>
                    <TextBlock Name="ownerRatingTextBlock" Grid.Row="5" Grid.Column="1"
                        Style="{StaticResource TextTextBlockStyleKey}"
                        Text="{Binding Path=Owner.Rating}" />
                    <TextBlock Name="ownerMemberSinceTitleTextBlock" Grid.Row="6" Grid.Column="0"
                        Style="{StaticResource SmallTitleTextBlockStyleKey}"
                        Margin="0 0 10 0">
                        가입일 :
                    </TextBlock>
                    <TextBlock Name="memberSinceTextBlock" Grid.Row="6" Grid.Column="1"
                        Style="{StaticResource TextTextBlockStyleKey}"
                        Text="{Binding Path=Owner.MemberSince, Converter={StaticResource DateConverterKey}}" />
                </Grid>
            </DataTemplate>
        </ResourceDictionary>
    </Application.Resources>
</Application>

 

▶ MainApplication.xaml.cs

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

namespace TestProject
{
    /// <summary>
    /// 메인 애플리케이션
    /// </summary>
    public partial class MainApplication : Application
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 현재 사용자 - CurrentUser

        /// <summary>
        /// 현재 사용자
        /// </summary>
        public User CurrentUser { get; set; }

        #endregion
        #region 옥션 항목 컬렉션 - AuctionItemCollection

        /// <summary>
        /// 옥션 항목 컬렉션
        /// </summary>
        public ObservableCollection<AuctionItem> AuctionItemCollection { get; set; } = new ObservableCollection<AuctionItem>();

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainApplication()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainApplication()
        {
            Startup += Application_Startup;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event

        #region 애플리케이션 시작시 처리하기 - Application_Startup(sender, e)

        /// <summary>
        /// 애플리케이션 시작시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            LoadAuctionData();
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Function

        #region 옥션 데이터 로그하기 - LoadAuctionData()

        /// <summary>
        /// 옥션 데이터 로그하기
        /// </summary>
        private void LoadAuctionData()
        {
            CurrentUser = new User("John", 12, new DateTime(2003, 4, 20));

            #region 옥션 항목 컬렉션에 추가한다.

            User maryUser = new User("Mary", 10, new DateTime(2000,  5,  2));
            User annaUser = new User("Anna",  5, new DateTime(2001,  9, 13));
            User mikeUser = new User("Mike", 13, new DateTime(1999, 11, 23));
            User markUser = new User("Mark", 15, new DateTime(2004,  6,  3));

            AuctionItem cameraAuctionItem = new AuctionItem
            (
                "Digital camera - good condition",
                ProductCategory.Electronics,
                300,
                new DateTime(2005, 8, 23),
                annaUser,
                SpecialFeatures.None
            );

            cameraAuctionItem.AddBid(new Bid(310, mikeUser));
            cameraAuctionItem.AddBid(new Bid(312, markUser));
            cameraAuctionItem.AddBid(new Bid(314, mikeUser));
            cameraAuctionItem.AddBid(new Bid(320, markUser));

            AuctionItem snowBoardAuctionItem = new AuctionItem
            (
                "Snowboard and bindings",
                ProductCategory.Sports,
                120,
                new DateTime(2005, 7, 12),
                mikeUser,
                SpecialFeatures.Highlight
            );

            snowBoardAuctionItem.AddBid(new Bid(140, annaUser));
            snowBoardAuctionItem.AddBid(new Bid(142, maryUser));
            snowBoardAuctionItem.AddBid(new Bid(150, annaUser));

            AuctionItem insideCSharpAuctionItem = new AuctionItem
            (
                "Inside C#, second edition",
                ProductCategory.Books,
                10,
                new DateTime(2005, 5, 29),
                CurrentUser,
                SpecialFeatures.Color
            );

            insideCSharpAuctionItem.AddBid(new Bid(11, markUser));
            insideCSharpAuctionItem.AddBid(new Bid(13, annaUser));
            insideCSharpAuctionItem.AddBid(new Bid(14, maryUser));
            insideCSharpAuctionItem.AddBid(new Bid(15, annaUser));

            AuctionItem laptopAuctionItem = new AuctionItem
            (
                "Laptop - only 1 year old",
                ProductCategory.Computers,
                500,
                new DateTime(2005, 8, 15),
                markUser,
                SpecialFeatures.Highlight
            );

            laptopAuctionItem.AddBid(new Bid(510, CurrentUser));

            AuctionItem chairSetAuctionItem = new AuctionItem
            (
                "Set of 6 chairs",
                ProductCategory.Home,
                120,
                new DateTime(2005, 2, 20),
                mikeUser,
                SpecialFeatures.Color
            );

            AuctionItem myDvdCollectionAuctionItem = new AuctionItem
            (
                "My DVD Collection",
                ProductCategory.DvDs,
                5,
                new DateTime(2005, 8, 3),
                maryUser,
                SpecialFeatures.Highlight
            );

            myDvdCollectionAuctionItem.AddBid(new Bid(6, mikeUser   ));
            myDvdCollectionAuctionItem.AddBid(new Bid(8, CurrentUser));

            AuctionItem tvDramaAuctionItem = new AuctionItem
            (
                "TV Drama Series",
                ProductCategory.DvDs,
                40,
                new DateTime(2005, 7, 28),
                annaUser,
                SpecialFeatures.None
            );

            tvDramaAuctionItem.AddBid(new Bid(42, mikeUser   ));
            tvDramaAuctionItem.AddBid(new Bid(45, markUser   ));
            tvDramaAuctionItem.AddBid(new Bid(50, mikeUser   ));
            tvDramaAuctionItem.AddBid(new Bid(51, CurrentUser));

            AuctionItem squashRacketAuctionItem = new AuctionItem
            (
                "Squash racket",
                ProductCategory.Sports,
                60,
                new DateTime(2005, 4, 4),
                markUser,
                SpecialFeatures.Highlight
            );

            squashRacketAuctionItem.AddBid(new Bid(62, mikeUser));
            squashRacketAuctionItem.AddBid(new Bid(65, annaUser));

            AuctionItemCollection.Add(cameraAuctionItem         );
            AuctionItemCollection.Add(snowBoardAuctionItem      );
            AuctionItemCollection.Add(insideCSharpAuctionItem   );
            AuctionItemCollection.Add(laptopAuctionItem         );
            AuctionItemCollection.Add(chairSetAuctionItem       );
            AuctionItemCollection.Add(myDvdCollectionAuctionItem);
            AuctionItemCollection.Add(tvDramaAuctionItem        );
            AuctionItemCollection.Add(squashRacketAuctionItem   );

            #endregion
        }

        #endregion
    }
}

 

▶ AddProductWindow.xaml

<Window x:Class="TestProject.AddProductWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestProject"
    Width="600"
    Height="480"
    Title="제품 추가"
    FontFamily="나눔고딕코딩"
    FontSize="16">
    <Window.Resources>
        <local:SpecialFeaturesConverter x:Key="SpecialFeaturesConverterKey" />
        <ControlTemplate x:Key="ValidationTemplateKey">
            <DockPanel>
                <TextBlock Foreground="Red" FontSize="20">!</TextBlock>
                <AdornedElementPlaceholder />
            </DockPanel>
        </ControlTemplate>
    </Window.Resources>
    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"    />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Border Grid.Row="0"
            Style="{StaticResource BorderStyleKey}">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*"    />
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"
                    Style="{StaticResource TitleTextBlockStyleKey}"
                    Margin="0 0 0 10">
                    판매 항목 :
                </TextBlock>
                <TextBlock Grid.Row="1" Grid.Column="0"
                    Style="{StaticResource SmallTitleTextBlockStyleKey}"
                    HorizontalAlignment="Right">
                    항목 설명 :
                </TextBlock>
                <TextBox Name="descriptionTextBox" Grid.Row="1" Grid.Column="1"
                    Style="{StaticResource TextTextBoxStyleKey}"
                    HorizontalAlignment="Left"
                    Margin="10 0 0 0"
                    Height="25">
                    <TextBox.Text>
                        <Binding
                            UpdateSourceTrigger="PropertyChanged"
                            NotifyOnValidationError="True"
                            Path="Description">
                            <Binding.ValidationRules>
                                <ExceptionValidationRule />
                            </Binding.ValidationRules>
                        </Binding>
                    </TextBox.Text>
                </TextBox>
                <TextBlock Grid.Row="2" Grid.Column="0"
                    Style="{StaticResource SmallTitleTextBlockStyleKey}"
                    HorizontalAlignment="Right"
                    Margin="0 5 0 0">
                    시작가 :
                </TextBlock>
                <TextBox Name="startPriceTextBox" Grid.Row="2" Grid.Column="1"
                    Style="{StaticResource TextTextBoxStyleKey}"
                    HorizontalAlignment="Left"
                    Height="25"
                    Margin="10 5 0 0">
                    <TextBox.Text>
                        <Binding
                            UpdateSourceTrigger="PropertyChanged"
                            NotifyOnValidationError="True"
                            Path="StartPrice" />
                    </TextBox.Text>
                </TextBox>
                <TextBlock Grid.Row="3" Grid.Column="0"
                    Style="{StaticResource SmallTitleTextBlockStyleKey}"
                    HorizontalAlignment="Right"
                    Margin="0 5 0 0">
                    시작일 :
                </TextBlock>
                <TextBox Name="startDateTextBox" Grid.Row="3" Grid.Column="1"
                    Validation.ErrorTemplate="{StaticResource ValidationTemplateKey}"
                    Style="{StaticResource TextTextBoxStyleKey}"
                    HorizontalAlignment="Left"
                    Margin="10 5 0 0"
                    Height="25">
                    <TextBox.Text>
                        <Binding
                            UpdateSourceTrigger="PropertyChanged"
                            NotifyOnValidationError="True"
                            Converter="{StaticResource DateConverterKey}"
                            Path="StartDate" />
                    </TextBox.Text>
                </TextBox>
                <TextBlock Grid.Row="4" Grid.Column="0"
                    Style="{StaticResource SmallTitleTextBlockStyleKey}"
                    HorizontalAlignment="Right"
                    Margin="0 5 0 0">
                    카테고리 :
                </TextBlock>
                <ComboBox Grid.Row="4" Grid.Column="1"
                    Style="{StaticResource ComboBoxStyleKey}"
                    ItemContainerStyle="{StaticResource ComboBoxItemStyleKey}"
                    HorizontalAlignment="Left"
                    Margin="10 5 0 0"
                    Width="150"
                    Height="25"
                    SelectedValue="{Binding Path=Category}">
                    <local:ProductCategory>Books</local:ProductCategory>
                    <local:ProductCategory>Computers</local:ProductCategory>
                    <local:ProductCategory>DvDs</local:ProductCategory>
                    <local:ProductCategory>Electronics</local:ProductCategory>
                    <local:ProductCategory>Home</local:ProductCategory>
                    <local:ProductCategory>Sports</local:ProductCategory>
                </ComboBox>
                <TextBlock Grid.Row="5" Grid.Column="0"
                    Style="{StaticResource SmallTitleTextBlockStyleKey}"
                    HorizontalAlignment="Right"
                    Margin="0 5 0 0">
                    특수 기능 :
                </TextBlock>
                <ComboBox Grid.Row="5" Grid.Column="1"
                    Style="{StaticResource ComboBoxStyleKey}"
                    ItemContainerStyle="{StaticResource ComboBoxItemStyleKey}"
                    HorizontalAlignment="Left"
                    Margin="10 5 0 0"
                    Width="150"
                    Height="25"
                    SelectedValue="{Binding Path=SpecialFeatures}">
                    <local:SpecialFeatures>None</local:SpecialFeatures>
                    <local:SpecialFeatures>Color</local:SpecialFeatures>
                    <local:SpecialFeatures>Highlight</local:SpecialFeatures>
                    <ComboBox.IsEnabled>
                        <MultiBinding Converter="{StaticResource SpecialFeaturesConverterKey}">
                            <Binding Source="{x:Static Application.Current}" Path="CurrentUser.Rating"      />
                            <Binding Source="{x:Static Application.Current}" Path="CurrentUser.MemberSince" />
                        </MultiBinding>
                    </ComboBox.IsEnabled>
                </ComboBox>
                <Button Name="submitButton" Grid.Row="6" Grid.Column="1"
                    HorizontalAlignment="Right"
                    Margin="10"
                    Width="100"
                    Height="30"
                    Content="제출" />
            </Grid>
        </Border>
        <ContentControl Name="ShortPreview" Grid.Row="1"
            HorizontalAlignment="Left"
            IsTabStop="False"
            Content="{Binding}" />
        <ContentControl Name="LongPreview" Grid.Row="2"
            ContentTemplate="{StaticResource DetailsProductListingTemplateKey}"
            HorizontalAlignment="Left"
            IsTabStop="False"
            Content="{Binding}" />
    </Grid>
</Window>

 

▶ AddProductWindow.xaml.cs

using System;
using System.Windows;

namespace TestProject
{
    /// <summary>
    /// 제품 추가 윈도우
    /// </summary>
    public partial class AddProductWindow : Window
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - AddProductWindow()

        /// <summary>
        /// 생성자
        /// </summary>
        public AddProductWindow()
        {
            InitializeComponent();

            Loaded                  += Window_Loaded;
            this.submitButton.Click += submitButton_Click;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 윈도우 로드시 처리하기 - Window_Loaded(sender, e)

        /// <summary>
        /// 윈도우 로드시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            DataContext = new AuctionItem
            (
                "Type your description here",
                ProductCategory.DvDs,
                1,
                DateTime.Now,
                ((MainApplication) Application.Current).CurrentUser,
                SpecialFeatures.None
            );
        }

        #endregion
        #region 제출 버튼 클릭시 처리하기 - submitButton_Click(sender, e)

        /// <summary>
        /// 제출 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void submitButton_Click(object sender, RoutedEventArgs e)
        {
            AuctionItem item = DataContext as AuctionItem;

            ((MainApplication) Application.Current).AuctionItemCollection.Add(item);

            Close();
        }

        #endregion
    }
}

 

▶ MainWindow.xaml

<Window x:Class="TestProject.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="800"
    Height="600"
    Title="TestProject"
    FontFamily="나눔고딕코딩"
    FontSize="16">
    <Window.Resources>
        <DataTemplate x:Key="GroupingHeaderTemplate">
            <TextBlock
                Style="{StaticResource GroupHeaderTextBlockStyleKey}"
                Text="{Binding Path=Name}" />
        </DataTemplate>
        <CollectionViewSource x:Key="CollectionViewSourceKey"
            Source="{Binding Source={x:Static Application.Current}, Path=AuctionItemCollection}" />
    </Window.Resources>
    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*"    />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Row="0" Grid.ColumnSpan="3"
            Style="{StaticResource TitleTextBlockStyleKey}"
            Margin="0 0 0 10">
            판매 물품 목록 :
        </TextBlock>
        <CheckBox Name="categoryCheckBox" Grid.Row="1" Grid.Column="0"
            Style="{StaticResource CheckBoxStyleKey}"
            Margin="10">
            카테고리별
        </CheckBox>
        <CheckBox Name="showOnlyBarginsCheckBox" Grid.Row="1" Grid.Column="1"
            Style="{StaticResource CheckBoxStyleKey}"
            Margin="10">
            할인만 표시
        </CheckBox>
        <CheckBox Name="sortByCategoryAndDateCheckBox" Grid.Row="1" Grid.Column="2"
            Style="{StaticResource CheckBoxStyleKey}"
            Margin="10">
            카테고리/날짜 정렬
        </CheckBox>
        <ListBox Grid.Row="2" Grid.ColumnSpan="3"
            ItemsSource="{Binding Source={StaticResource CollectionViewSourceKey}}">
            <ListBox.GroupStyle>
                <GroupStyle HeaderTemplate="{StaticResource GroupingHeaderTemplate}" />
            </ListBox.GroupStyle>
        </ListBox>
        <ContentControl Grid.Row="3" Grid.ColumnSpan="3"
            ContentTemplate="{StaticResource DetailsProductListingTemplateKey}"
            Margin="0 10 0 0"
            IsTabStop="False"
            Content="{Binding Source={StaticResource CollectionViewSourceKey}}" />
        <Button Name="addProductButton" Grid.Row="4" Grid.Column="1"
            HorizontalAlignment="Center"
            Margin="10"
            Width="120"
            Height="30"
            Content="제품 추가" />
    </Grid>
</Window>

 

▶ MainWindow.xaml.cs

using System.ComponentModel;
using System.Windows;
using System.Windows.Data;

namespace TestProject
{
    /// <summary>
    /// 메인 윈도우
    /// </summary>
    public partial class MainWindow : Window
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 컬렉션 뷰 소스
        /// </summary>
        private readonly CollectionViewSource collectionViewSource;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainWindow()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();

            this.collectionViewSource = Resources["CollectionViewSourceKey"] as CollectionViewSource;

            this.categoryCheckBox.Checked                += categoryCheckBox_Checked;
            this.categoryCheckBox.Unchecked              += categoryCheckBox_Unchecked;
            this.showOnlyBarginsCheckBox.Checked         += showOnlyBarginsCheckBox_Checked;
            this.showOnlyBarginsCheckBox.Unchecked       += showOnlyBarginsCheckBox_Unchecked;
            this.sortByCategoryAndDateCheckBox.Checked   += sortByCategoryAndDateCheckBox_Checked;
            this.sortByCategoryAndDateCheckBox.Unchecked += sortByCategoryAndDateCheckBox_Unchecked;
            this.addProductButton.Click                  += addProductButton_Click;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 카테고리 체크 박스 체크시 처리하기 - categoryCheckBox_Checked(sender, e)

        /// <summary>
        /// 카테고리 체크 박스 체크시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void categoryCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            PropertyGroupDescription propertyGroupDescription = new PropertyGroupDescription { PropertyName = "Category" };

            this.collectionViewSource.GroupDescriptions.Add(propertyGroupDescription);
        }

        #endregion
        #region 카테고리 체크 박스 체크 해제시 처리하기 - categoryCheckBox_Unchecked(sender, e)

        /// <summary>
        /// 카테고리 체크 박스 체크 해제시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void categoryCheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            this.collectionViewSource.GroupDescriptions.Clear();
        }

        #endregion
        #region 컬렉션 뷰 소스 필터시 처리하기 - collectionViewSource_Filter(sender, e)

        /// <summary>
        /// 컬렉션 뷰 소스 필터시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void collectionViewSource_Filter(object sender, FilterEventArgs e)
        {
            AuctionItem item = e.Item as AuctionItem;

            if(item != null)
            {
                e.Accepted = item.CurrentPrice < 25;
            }
        }

        #endregion
        #region 할인만 표시 체크 박스 체크시 처리하기 - showOnlyBarginsCheckBox_Checked(sender, e)

        /// <summary>
        /// 할인만 표시 체크 박스 체크시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void showOnlyBarginsCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            this.collectionViewSource.Filter += collectionViewSource_Filter;
        }

        #endregion
        #region 할인만 표시 체크 박스 체크 해제시 처리하기 - showOnlyBarginsCheckBox_Unchecked(sender, e)

        /// <summary>
        /// 할인만 표시 체크 박스 체크 해제시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void showOnlyBarginsCheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            this.collectionViewSource.Filter -= collectionViewSource_Filter;
        }

        #endregion
        #region 카테고리/날짜 정렬 체크 박스 체크시 처리하기 - sortByCategoryAndDateCheckBox_Checked(sender, e)

        /// <summary>
        /// 카테고리/날짜 정렬 체크 박스 체크시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void sortByCategoryAndDateCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            this.collectionViewSource.SortDescriptions.Add(new SortDescription("Category" , ListSortDirection.Ascending));
            this.collectionViewSource.SortDescriptions.Add(new SortDescription("StartDate", ListSortDirection.Ascending));
        }

        #endregion
        #region 카테고리/날짜 정렬 체크 박스 체크 해제시 처리하기 - sortByCategoryAndDateCheckBox_Unchecked(sender, e)

        /// <summary>
        /// 카테고리/날짜 정렬 체크 박스 체크 해제시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void sortByCategoryAndDateCheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            this.collectionViewSource.SortDescriptions.Clear();
        }

        #endregion
        #region 제품 추가 버튼 클릭시 처리하기 - addProductButton_Click(sender, e)

        /// <summary>
        /// 제품 추가 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void addProductButton_Click(object sender, RoutedEventArgs e)
        {
            AddProductWindow window = new AddProductWindow();

            window.ShowDialog();
        }

        #endregion
    }
}
728x90
그리드형(광고전용)
Posted by icodebroker
,