728x90
반응형

EventAggregator 는 이벤트들을 구독하거나 구독기능을 제공하며

컴포넌트 간의 이벤트 처리를 직접적인 참조 없이 가능하게 해줍니다.

 

MainWindow.xaml

<Window x:Class="WpfAppPrism.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        mc:Ignorable="d"

        Title="MainWindow" Height="450" Width="800">

    <StackPanel VerticalAlignment="Center">

        <Button Name="testButton" Content="Click!" Height="100" Width="200" HorizontalAlignment="Center" Click="testButton_Click"/>

        <Label Content=""/>

        <Button Name="unsubscribeButton" Content="Unsubscribe" Height="100" Width="200" HorizontalAlignment="Center" Click="unsubscribeButton_Click"/>

    </StackPanel>

</Window>

 

 

MainWindow.xaml.cs

using Microsoft.Practices.Composite.Events;

using Microsoft.Practices.Composite.Presentation.Events;

 

using System.Windows;

 

namespace WpfAppPrism

{

    /// <summary>

    /// string 을 인자를 가지는 이벤트 입니다.

    /// CompositePresentationEvent 는 이벤트 게시 및 구독을 관리하는 클래스입니다.

    /// </summary>

    public class SampleStringEvent : CompositePresentationEvent<string> { }

 

    public partial class MainWindow : Window

    {

        /// <summary>

        /// EventAggregator 입니다.

        /// </summary>

        EventAggregator aggregator = new EventAggregator();

 

        /// <summary>

        /// 구독 토큰입니다.

        /// </summary>

        private SubscriptionToken subscriptionToken;

 

        public MainWindow()

        {

            InitializeComponent();

 

            // 이벤트를 구독합니다.

            this.aggregator.GetEvent<SampleStringEvent>().Subscribe(StringAction1);

 

            //이벤트를 구독하고 구독취소를 위해 SubscriptionToken 을 받습니다.

            this.subscriptionToken = this.aggregator.GetEvent<SampleStringEvent>().Subscribe(StringAction2);

        }

 

        /// <summary>

        /// 이벤트 1 입니다.

        /// </summary>

        /// <param name="s"></param>

        private void StringAction1(string s)

        {

            MessageBox.Show($"{s}.StringAction1");

        }

 

        /// <summary>

        /// 이벤트 2 입니다.

        /// </summary>

        /// <param name="s"></param>

        private void StringAction2(string s)

        {

            MessageBox.Show($"{s}.StringAction2");

        }

 

        /// <summary>

        /// test 버튼 클릭 이벤트입니다.

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void testButton_Click(object sender, RoutedEventArgs e)

        {

            // Subscribe 된 이벤트를 실행합니다.

            this.aggregator.GetEvent<SampleStringEvent>().Publish("testButton");

        }

 

        /// <summary>

        /// Unsubscribe 버튼 클릭 이벤트입니다.

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void unsubscribeButton_Click(object sender, RoutedEventArgs e)

        {

            // 이벤트 하나를 Unsubscribe 합니다.

            this.aggregator.GetEvent<SampleStringEvent>().Unsubscribe(this.subscriptionToken);

        }

    }

}

 

 

 

우선 Click! 버튼을 클릭하면 "testButton.StringAction2" 메세지 박스가 나온후 "testButton.StringAction1" 메세지 박스가 나타난다.

구독한 순서 역순으로 이벤트는 발생된다.

 

여기서 Unsubscribe 버튼을 클릭하면 "testButton.StringAction1" 메세지 박스만 나타난다.




 

 

728x90
반응형
728x90
반응형

이미지를 특정 모양 부분만 보이도록 하는 방법입니다.

Clip 에 패스미니언어를 이용하면됩니다.

 

<Window x:Class="WpfApp3.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        mc:Ignorable="d"

        Title="MainWindow" Height="450" Width="600">

    <Image

         Clip="M 220 170 L 170 390 L 370 390 L 320 170 A 70 70 0 1 0 220 170"

         Stretch="None"

         Source="http://img2.yna.co.kr/etc/inner/KR/2019/09/09/AKR20190909107200009_04_i_P4.jpg" />

</Window>

 

 

728x90
반응형
728x90
반응형

CollectionView 는 필터를 적용할수 있습니다.

bool 값을 반환하는 메서드를 만들어 Filter 에 적용시키면됩니다.

 

bool 값을 반환하는 메서드를 아래 처럼 정의하고

* "K" 로 시작하는 값만 필터링하게 합니다.

 

        bool NameFilter(object obj)

        {

            return (obj as Person).Name.StartsWith

            (

                "K",

                StringComparison.CurrentCultureIgnoreCase

            );

        }

 

CollectionView 의 Filter = NameFilter; 로 적용하면 됩니다.

 

아래는 예시 코드입니다.

 

Person.cs

using System.ComponentModel;

 

namespace WpfApp

{

    public class Person : INotifyPropertyChanged

    {

        /// <summary>

        /// 속성변경 이벤트입니다.

        /// </summary>

        public event PropertyChangedEventHandler PropertyChanged;

 

        /// <summary>

        /// 이름입니다.

        /// </summary>

        string name = "";

 

        /// <summary>

        /// 별명입니다.

        /// </summary>

        string nickName = "";

 

        /// <summary>

        /// 이름입니다.

        /// </summary>

        public string Name

        {

            set

            {

                this.name = value;

                OnPropertyChanged(nameof(Name));

            }

            get { return name; }

        }

 

        /// <summary>

        /// 별명입니다.

        /// </summary>

        public string NickName

        {

            set

            {

                nickName = value;

                OnPropertyChanged(nameof(NickName));

            }

            get { return nickName; }

        }

 

        /// <summary>

        /// 속성 값이 변경될 때 발생합니다.

        /// </summary>

        /// <param name="propertyName"></param>

        protected virtual void OnPropertyChanged(string propertyName)

        {

            if (PropertyChanged != null)

            {

                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

            }

        }

    }

}

 

 

MainWindow.xaml

<Window x:Class="WpfApp3.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        mc:Ignorable="d"

        Title="MainWindow" Height="450" Width="400">

    <StackPanel>

        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="10">

            <TextBox Name="searchTextBox" Text="" Width="200" VerticalContentAlignment="Center"/>

            <Button Name="searchButton" Content="Search" Padding="5" Margin="5" Click="searchButton_Click"/>

        </StackPanel>

        <TextBox

            Margin="12" Height="50" VerticalContentAlignment="Center"

            Text="{Binding Name,

                   Mode=TwoWay,

                   UpdateSourceTrigger=PropertyChanged}" />

        <TextBox

            Margin="12" Height="50" VerticalContentAlignment="Center"

            Text="{Binding NickName,

                   Mode=TwoWay,

                   UpdateSourceTrigger=PropertyChanged}" />

        

        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">

            <Button Name="prevButton" Content="Prev" Padding="10" Margin="10" Click="prevButton_Click"/>

            <Button Name="nextButton" Content="Next" Padding="10" Margin="10" Click="nextButton_Click"/>

        </StackPanel>

    </StackPanel>

</Window>

 

 

MainWindow.xaml.cs

using System;

using System.Collections.ObjectModel;

using System.ComponentModel;

using System.Linq;

using System.Windows;

using System.Windows.Data;

 

namespace WpfApp3

{

    public partial class MainWindow : Window

    {

        /// <summary>

        /// 데이터 collectionView 입니다.

        /// </summary>

        ICollectionView collectionView;

 

        public MainWindow()

        {

            InitializeComponent();

 

            ObservableCollection<Person> datas = new ObservableCollection<Person>();

 

            datas.Add(new Person() { Name = "Kang",  NickName = "Super" });

            datas.Add(new Person() { Name = "An",    NickName = "Father" });

            datas.Add(new Person() { Name = "Jang",  NickName = "Marvel" });

            datas.Add(new Person() { Name = "Joo",   NickName = "Mother" });

            datas.Add(new Person() { Name = "Kim",   NickName = "DC" });

 

            this.collectionView = CollectionViewSource.GetDefaultView(datas);

            this.collectionView.Filter = NameFilter;

            this.collectionView.CurrentChanged += CollectionView_CurrentChanged; ;

 

            this.collectionView.SortDescriptions.Add(new SortDescription(nameof(Person.Name), ListSortDirection.Ascending));

 

            this.DataContext = this.collectionView;

 

            // 처음값으로 이동시킵니다.

            this.collectionView.MoveCurrentToFirst();

        }

 

        /// <summary>

        /// 이전 값으로 이동하는 버튼 클릭이벤트입니다.

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void prevButton_Click(object sender, RoutedEventArgs e)

        {

            this.collectionView.MoveCurrentToPrevious();

        }

 

        /// <summary>

        /// 다음 값으로 이동하는 버튼 클릭이벤트입니다.

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void nextButton_Click(object sender, RoutedEventArgs e)

        {

            this.collectionView.MoveCurrentToNext();

        }

 

        /// <summary>

        /// CollectionView 현재값이 변경되었을때 발생되는 이벤트입니다.

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="args"></param>

        private void CollectionView_CurrentChanged(object sender, EventArgs e)

        {

            // 이전/다음 항목 존재여부에 따라 이전/다음 버튼을 활성화하거나 비활성화 합니다.

            this.prevButton.IsEnabled = this.collectionView.CurrentPosition > 0;

            this.nextButton.IsEnabled = this.collectionView.CurrentPosition < this.collectionView.Cast<object>().Count() - 1;

        }

 

        /// <summary>

        /// Search 버튼 클릭이벤트입니다.

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void searchButton_Click(object sender, RoutedEventArgs e)

        {

            // Refresh 하여 필터 적용된 내용이 보이도록합니다.

            this.collectionView.Refresh();

        }

 

        /// <summary>

        /// 이름 기준 필터입니다.

        /// </summary>

        /// <param name="obj"></param>

        /// <returns></returns>

        bool NameFilter(object obj)

        {

            return (obj as Person).Name.StartsWith

            (

                this.searchTextBox.Text,

                StringComparison.CurrentCultureIgnoreCase

            );

        }

    }

}

 

 

결과


결과를 보면 내용중에 필터링 된 내용만 볼수있도록 처리가 됩니다.


728x90
반응형
728x90
반응형

CollectionView 에 담겨진 데이터를 화면에 하나씩 나타내도록 하여

탐색하는 코드를 알아봅니다.

 

Person.cs

using System.ComponentModel;

 

namespace WpfApp

{

    public class Person : INotifyPropertyChanged

    {

        /// <summary>

        /// 속성변경 이벤트입니다.

        /// </summary>

        public event PropertyChangedEventHandler PropertyChanged;

 

        /// <summary>

        /// 이름입니다.

        /// </summary>

        string name = "";

 

        /// <summary>

        /// 별명입니다.

        /// </summary>

        string nickName = "";

 

        /// <summary>

        /// 이름입니다.

        /// </summary>

        public string Name

        {

            set

            {

                this.name = value;

                OnPropertyChanged(nameof(Name));

            }

            get { return name; }

        }

 

        /// <summary>

        /// 별명입니다.

        /// </summary>

        public string NickName

        {

            set

            {

                nickName = value;

                OnPropertyChanged(nameof(NickName));

            }

            get { return nickName; }

        }

 

        /// <summary>

        /// 속성 값이 변경될 때 발생합니다.

        /// </summary>

        /// <param name="propertyName"></param>

        protected virtual void OnPropertyChanged(string propertyName)

        {

            if (PropertyChanged != null)

            {

                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

            }

        }

    }

}

 

 

MainWindow.xaml

<Window x:Class="WpfApp.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        mc:Ignorable="d"

        Title="MainWindow" Height="450" Width="400">

    <StackPanel>

        <TextBox

            Margin="12" Height="50" VerticalContentAlignment="Center"

            Text="{Binding Name,

                   Mode=TwoWay,

                   UpdateSourceTrigger=PropertyChanged}" />

        <TextBox

            Margin="12" Height="50" VerticalContentAlignment="Center"

            Text="{Binding NickName,

                   Mode=TwoWay,

                   UpdateSourceTrigger=PropertyChanged}" />

        

        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">

            <Button Name="prevButton" Content="Prev" Padding="10" Margin="10" Click="prevButton_Click"/>

            <Button Name="nextButton" Content="Next" Padding="10" Margin="10" Click="nextButton_Click"/>

        </StackPanel>

    </StackPanel>

</Window>

 

 

MainWindow.xaml.cs

using System;

using System.Collections.ObjectModel;

using System.ComponentModel;

using System.Linq;

using System.Windows;

using System.Windows.Data;

 

namespace WpfApp

{

    public partial class MainWindow : Window

    {

        /// <summary>

        /// 데이터 collectionView 입니다.

        /// </summary>

        ICollectionView collectionView;

 

        public MainWindow()

        {

            InitializeComponent();

 

            ObservableCollection<Person> datas = new ObservableCollection<Person>();

 

            datas.Add(new Person(){ Name = "Kang",  NickName = "Super" });

            datas.Add(new Person(){ Name = "An",    NickName = "Father" });

            datas.Add(new Person(){ Name = "Jang",  NickName = "Marvel" });

 

            this.collectionView = CollectionViewSource.GetDefaultView(datas);

            this.collectionView.CurrentChanged += CollectionView_CurrentChanged; ;

 

            this.collectionView.SortDescriptions.Add(new SortDescription(nameof(Person.Name), ListSortDirection.Ascending));

 

            this.DataContext = this.collectionView;

 

            // 처음값으로 이동시킵니다.

            this.collectionView.MoveCurrentToFirst();

        }

 

        /// <summary>

        /// 이전 값으로 이동하는 버튼 클릭이벤트입니다.

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void prevButton_Click(object sender, RoutedEventArgs e)

        {

            this.collectionView.MoveCurrentToPrevious();

        }

 

        /// <summary>

        /// 다음 값으로 이동하는 버튼 클릭이벤트입니다.

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void nextButton_Click(object sender, RoutedEventArgs e)

        {

            this.collectionView.MoveCurrentToNext();

        }

 

        /// <summary>

        /// CollectionView 현재값이 변경되었을때 발생되는 이벤트입니다.

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="args"></param>

        private void CollectionView_CurrentChanged(object sender, EventArgs e)

        {

            // 이전/다음 항목 존재여부에 따라 이전/다음 버튼을 활성화하거나 비활성화 합니다.

            this.prevButton.IsEnabled = this.collectionView.CurrentPosition > 0;

            this.nextButton.IsEnabled = this.collectionView.CurrentPosition < this.collectionView.Cast<object>().Count() - 1;

        }

    }

}

 

 


 

728x90
반응형
728x90
반응형

CollectionView 를 이용해 다양한 기능을 처리할수 있습니다.

여기선 데이터 정렬하는 기능을 알아봅니다.

 

먼저 데이터로 사용할 Class 를 정의합니다.

 

Person.cs

 

using System.ComponentModel;

 

namespace WpfApp

{

    public class Person : INotifyPropertyChanged

    {

        /// <summary>

        /// 속성변경 이벤트입니다.

        /// </summary>

        public event PropertyChangedEventHandler PropertyChanged;

 

        /// <summary>

        /// 이름입니다.

        /// </summary>

        string name = "";

 

        /// <summary>

        /// 별명입니다.

        /// </summary>

        string nickName = "";

 

        /// <summary>

        /// 이름입니다.

        /// </summary>

        public string Name

        {

            set

            {

                this.name = value;

                OnPropertyChanged(nameof(Name));

            }

            get { return name; }

        }

 

        /// <summary>

        /// 별명입니다.

        /// </summary>

        public string NickName

        {

            set

            {

                nickName = value;

                OnPropertyChanged(nameof(NickName));

            }

            get { return nickName; }

        }

 

        /// <summary>

        /// 속성 값이 변경될 때 발생합니다.

        /// </summary>

        /// <param name="propertyName"></param>

        protected virtual void OnPropertyChanged(string propertyName)

        {

            if (PropertyChanged != null)

            {

                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

            }

        }

    }

}

 

 

MainWindow.xaml

<Window x:Class="WpfApp.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        mc:Ignorable="d"

        Title="MainWindow" Height="450" Width="800">

    <StackPanel>

        <ListBox Name="listbox" Width="300" Height="300" Margin="24">

            <ListBox.ItemTemplate>

                <DataTemplate>

                    <StackPanel Orientation="Horizontal">

                        <TextBlock Text="{Binding Name}" />

                        <TextBlock Text="      " />

                        <TextBlock Text="{Binding NickName}" />

                    </StackPanel>

                </DataTemplate>

            </ListBox.ItemTemplate>

        </ListBox>

    </StackPanel>

</Window>

 

 

MainWindow.xaml.cs

 

using System.Collections.ObjectModel;

using System.ComponentModel;

using System.Windows;

using System.Windows.Data;

 

namespace WpfApp

{

    public partial class MainWindow : Window

    {

        public MainWindow()

        {

            InitializeComponent();

 

            ObservableCollection<Person> datas = new ObservableCollection<Person>();

 

            datas.Add(new Person(){ Name = "Kang",  NickName = "Super" });

            datas.Add(new Person(){ Name = "An",    NickName = "Father" });

            datas.Add(new Person(){ Name = "Jang",  NickName = "Marvel" });

 

            ICollectionView collectionView = CollectionViewSource.GetDefaultView(datas);

 

            collectionView.SortDescriptions.Add(new SortDescription(nameof(Person.Name), ListSortDirection.Ascending));

 

            this.listbox.ItemsSource = collectionView;

        }

    }

}

 

 

위 코드에서 보듯이 CollectionView 의 SortDescriptions 를 사용하여 정렬기준을 줄수 있습니다.

 

 

 

728x90
반응형
728x90
반응형

ControlTemplate 은 컨트롤의 모습이나 이벤트 처리등을 미리 정의해 놓고 가져다 쓰는 것을 말합니다.

아래 예시를 보시면 아시겠지만 RadioButton 앞의 라디오 박스가 사라지고

선택시 글자를 굵게 표시하고 주변으로 사각형이 그려집니다.

 

<Window x:Class="WpfApp.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        mc:Ignorable="d"

        Title="MainWindow" Height="450" Width="800">

    <StackPanel>

        <StackPanel.Resources>

            <ControlTemplate

                 x:Key="rectRadioButton"

                 TargetType="{x:Type RadioButton}">

                <Border

                    Name="border"

                    BorderBrush="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"

                    CornerRadius="0"

                    Padding="10"

                    BorderThickness="0"

                    Margin="2"

                    Width="250">

                    <ContentPresenter

                        Content="{TemplateBinding ContentControl.Content}" HorizontalAlignment="Center"/>

                </Border>

                <ControlTemplate.Triggers>

                    <Trigger

                         Property="IsChecked"

                         Value="True">

                        <Setter

                             TargetName="border"

                             Property="BorderThickness"

                             Value="3" />

                        <Setter

                             Property="FontWeight"

                             Value="Bold" />

                    </Trigger>

                </ControlTemplate.Triggers>

            </ControlTemplate>

        </StackPanel.Resources>

        <GroupBox

             HorizontalAlignment="Center"

             VerticalAlignment="Center"

             FontSize="12pt"

             Header="Select Option">

            <StackPanel>

                <RadioButton

                    Template="{StaticResource rectRadioButton}"

                    HorizontalAlignment="Center"

                    Content="Template RadioButton 1"

                    IsChecked="True" />

                <RadioButton

                     Template="{StaticResource rectRadioButton}"

                     HorizontalAlignment="Center"

                     Content="Template RadioButton 2" />

                <RadioButton

                     Template="{StaticResource rectRadioButton}"

                     HorizontalAlignment="Center"

                     Content="Template RadioButton 3" />

                <RadioButton

                     Template="{StaticResource rectRadioButton}"

                     HorizontalAlignment="Center"

                     Content="Template RadioButton 4" />

            </StackPanel>

        </GroupBox>

    </StackPanel>

</Window>

 

 

 

728x90
반응형
728x90
반응형

Style.Triggers 를 이용하여 Control 에 액션을 취한경우 어떠한 처리를 할 수 있습니다.

아래 예시는 Button, Label 에 마우스를 올렸을때 글자가 파란색으로 굵게 나타도록 한 것입니다.

Button 은 클릭시 글자 색을 변경합니다.

 

<Window x:Class="WpfApp3.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        mc:Ignorable="d"

        Title="MainWindow" Height="450" Width="800">

    <StackPanel>

        <StackPanel.Resources>

            <Style

                x:Key="normal">

                <Setter

                    Property="Control.FontSize"

                    Value="20" />

                <Setter

                    Property="Control.HorizontalAlignment"

                    Value="Center" />

                <Style.Triggers>

                    <Trigger

                        Property="Control.IsMouseOver"

                        Value="true">

                        <Setter

                            Property="Control.FontWeight"

                            Value="Bold" />

                        <Setter

                            Property="Control.Foreground"

                            Value="Blue" />

                    </Trigger>

                    <Trigger

                        Property="Button.IsPressed"

                        Value="true">

                        <Setter

                            Property="Control.Foreground"

                            Value="Red" />

                    </Trigger>

                </Style.Triggers>

            </Style>

        </StackPanel.Resources>

        <Button Style="{StaticResource normal}" Content="Test Button"/>

        <Label Style="{StaticResource normal}" Content="Test Label"/>

    </StackPanel>

</Window>

 

 

 

* MouseOver

  >     >

 

* Button Click

 

728x90
반응형
WPF
728x90
반응형

Style 은 컨트롤의 요소들을 미리 정의해 놓고 쓰기위한 것이라고 보면됩니다.

 

아래 코드와 같이 같은 크기의 색이 다른 원을 그린다고 할때 크기를 미리 정의해 놓고 쓰게되면

색만 바꿔처리하면 되므로 코딩이 간결해집니다.

 

<Window x:Class="WpfApp3.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        mc:Ignorable="d"

        Title="MainWindow" Height="450" Width="800">

    <Canvas>

        <Canvas.Resources>

            <Style

                TargetType="{x:Type Ellipse}">

                <Setter

                     Property="Width"

                     Value="96" />

                <Setter

                     Property="Height"

                     Value="96" />

            </Style>

        </Canvas.Resources>

        <Ellipse Canvas.Left="100" Canvas.Top="50" Fill="Blue" />

        <Ellipse Canvas.Left="150" Canvas.Top="100" Fill="Red" />

        <Ellipse Canvas.Left="200" Canvas.Top="150" Fill="Green" />

    </Canvas>

</Window>

 

 

 

 

또한 미리 정의한 style 을 기본베이스로 삼아 특정속성을 바꿔 style 을 재정의 할수 있습니다.

 

<Window x:Class="WpfApp3.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        mc:Ignorable="d"

        Title="MainWindow" Height="450" Width="800">

    <Canvas>

        <Canvas.Resources>

            <Style

                TargetType="{x:Type Ellipse}">

                <Setter

                     Property="Width"

                     Value="96" />

                <Setter

                     Property="Height"

                     Value="96" />

            </Style>

            <Style

                x:Key="otherEllipse"

                TargetType="{x:Type Ellipse}"

                BasedOn ="{StaticResource {x:Type Ellipse}}">

                <Setter

                     Property="Width"

                     Value="150" />

                <Setter

                     Property="Height"

                     Value="150" />

            </Style>

        </Canvas.Resources>

        <Ellipse Canvas.Left="100" Canvas.Top="50" Fill="Blue" />

        <Ellipse Canvas.Left="150" Canvas.Top="100" Fill="Red" />

        <Ellipse Canvas.Left="200" Canvas.Top="150" Fill="Green" Style="{StaticResource otherEllipse}" />

    </Canvas>

</Window>

 

 

 

728x90
반응형
728x90
반응형

RelativeSource 는 엘리먼트 트리 내에 조상 엘리먼트나 엘리먼트 그

자체를 참조하여 바인딩을 처리합니다.

 

아래 코드를 보면

<Window x:Class="WpfApp.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        xmlns:src="clr-namespace:WpfApp"

        mc:Ignorable="d"

        Title="MainWindow" Height="450" Width="800">

    <StackPanel>

        <StackPanel

            Orientation="Horizontal"

            HorizontalAlignment="Center">

            <TextBlock

                Text="{Binding RelativeSource={RelativeSource self}, Path=FontFamily}" />

        </StackPanel>

        <StackPanel

            Orientation="Horizontal"

            HorizontalAlignment="Center">

            <TextBlock

                Text= "{Binding RelativeSource={RelativeSource AncestorType={x:Type StackPanel}}, Path=Orientation}" />

        </StackPanel>

    </StackPanel>

</Window>

 

 

self 는 자기 자신을 가리키며 두번째는 AncestorType 으로 앨리먼트 트리에 StackPanel 을 가리키게 됩니다.

728x90
반응형

'WPF' 카테고리의 다른 글

[WPF] Style.Triggers 이용하여 Control 변화 주기  (0) 2020.07.10
[WPF] Style 사용하기  (0) 2020.07.10
[WPF] RelativeSource 를 이용한 바인딩  (0) 2020.07.10
[WPF] IValueConverter 사용하기  (0) 2020.07.10
[WPF] Custom FrameworkElement 사용하기  (0) 2020.07.10
[WPF] Binding  (0) 2020.07.09
728x90
반응형

IValueConverter 는 서로 다른 데이터 타입 사이의 데이터 바인딩을

처리하기 위해 사용하게 됩니다.

ConvertBack 메소드는 Mode 가 Twoway 방식일 때 사용됩니다.

 

실제 값이 숫자라고 할때 바인딩 대상은 문자를 요구할때 등의 상황에 쓰일수 있습니다.

 

아래는 double 값을 decimal 값으로 변환하되 인자 값에 따라 소숫점 뒷자리를 잘라내는 코드입니다.

 

DoubleToDecimalConverter.cs

using System;

using System.Globalization;

using System.Windows.Data;

 

namespace WpfApp

{

    [ValueConversion(typeof(double), typeof(decimal))]

    public class DoubleToDecimalConverter : IValueConverter

    {

        /// <summary>

        /// 값을 변환합니다.

        /// </summary>

        /// <param name="value">바인딩 소스에서 생성한 값입니다.</param>

        /// <param name="typeTarget">바인딩 대상 속성의 형식입니다.</param>

        /// <param name="parameter">사용할 변환기 매개 변수입니다.</param>

        /// <param name="culture">변환기에서 사용할 문화권입니다.</param>

        /// <returns>변환된 값입니다. 메서드에서 null을 반환하면 유효한 null 값이 사용됩니다.</returns>

        public object Convert(object value, Type typeTarget, object parameter, CultureInfo culture)

        {

            decimal num = new Decimal((double)value);

            if (parameter != null)

            {

                num = Decimal.Round(num, Int32.Parse(parameter as string));

            }

            return num;

        }

 

        /// <summary>

        /// 값을 변환합니다.

        /// </summary>

        /// <param name="value">바인딩 소스에서 생성한 값입니다.</param>

        /// <param name="typeTarget">바인딩 대상 속성의 형식입니다.</param>

        /// <param name="parameter">사용할 변환기 매개 변수입니다.</param>

        /// <param name="culture">변환기에서 사용할 문화권입니다.</param>

        /// <returns>변환된 값입니다. 메서드에서 null을 반환하면 유효한 null 값이 사용됩니다.</returns>

        public object ConvertBack(object value, Type typeTarget, object parameter, CultureInfo culture)

        {

            return Decimal.ToDouble((decimal)value);

        }

    }

}

 

 

 

MainWindow.xaml

<Window x:Class="WpfApp.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        xmlns:src="clr-namespace:WpfApp"

        mc:Ignorable="d"

        Title="MainWindow" Height="450" Width="800">

    <Window.Resources>

        <src:DoubleToDecimalConverter x:Key="converter" />

    </Window.Resources>

    <StackPanel>

        <ScrollBar

             Name="scroll"

             Orientation="Horizontal"

             Margin="24"

             Maximum="100"

             LargeChange="10"

             SmallChange="1" />

        <Label

             HorizontalAlignment="Center"

             Content="{Binding ElementName=scroll, Path=Value, Mode=OneWay, Converter={StaticResource converter}, ConverterParameter=2}" />

    </StackPanel>

  </Window>

 

 

 

 

 

728x90
반응형

'WPF' 카테고리의 다른 글

[WPF] Style 사용하기  (0) 2020.07.10
[WPF] RelativeSource 를 이용한 바인딩  (0) 2020.07.10
[WPF] IValueConverter 사용하기  (0) 2020.07.10
[WPF] Custom FrameworkElement 사용하기  (0) 2020.07.10
[WPF] Binding  (0) 2020.07.09
[WPF] PageFunction  (0) 2020.07.09

+ Recent posts