레이블이 WPF강의인 게시물을 표시합니다. 모든 게시물 표시
레이블이 WPF강의인 게시물을 표시합니다. 모든 게시물 표시

2022년 1월 22일 토요일

WPF Style, EventSetter, 다수의 컨트롤에서 이벤트 공유, e.handled, 이벤트라우팅, WPF동영상교육, WPF학원, C#학원, 닷넷학원, 닷넷교육, C#교육, WPF교육

 WPF Style, EventSetter, 다수의 컨트롤에서 이벤트 공유, e.handled, 이벤트라우팅, WPF동영상교육, WPF학원, C#학원, 닷넷학원, 닷넷교육, C#교육, WPF교육


https://www.youtube.com/watch?v=5-5yzocgj84&list=PLxU-iZCqT52Cmj47aKB1T-SxI33YL7rYS&index=24 

https://www.youtube.com/watch?v=sTOKEenyaSI&list=PLxU-iZCqT52Cmj47aKB1T-SxI33YL7rYS&index=23 


https://www.youtube.com/watch?v=Qj26gdH651A&list=PLxU-iZCqT52Cmj47aKB1T-SxI33YL7rYS&index=22 




WPF Style

다수의 컨트롤에서 이벤트 공유

EventSetter




  • Style의 EventSetter를 이용하여 이벤트에 대한 응답 핸들러 메소드를 지정할 수 있다.
  • Setter가 Style의 자식중 대체로 이용 되지만 라우팅된 특정 이벤트(버튼의 Click등)의 이벤트핸들러를 설정하기 위해서는 EventSetter 엘리먼트를 이용할 수 있는데 다수의 엘리먼트에서 이벤트를 공유할 수 있다.


[실습]

아래 예제에서 3개의 버튼이 존재하는데 각 버튼은 자체적인 클릭 이벤트를 가지고 있어 클릭을 하면 그 이벤트 핸들러가 실행되고 그 이후 Style에 적용된  EventSetter가 적용되어서 빨강색 브러시가 적용되어 배경이 붉은색으로 변경이 됩니다. 하지만 Button3는 e.handled=true가 되어 이벤트 라우팅이 중단되어 EventSetter의 핸들러 메소드가 호출되지 않는다.







[MainWindow.xaml]

<Window x:Class="WpfApp6.MainWindow"

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

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


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


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

        xmlns:local="clr-namespace:WpfApp6"

        mc:Ignorable="d"

        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>

        <Style TargetType="{x:Type Button}">

            <Setter Property="FontSize" Value="24" />

            <Setter Property="Background" Value="Yellow" />

            <EventSetter Event="Click" Handler="EventSetter_Click" />

        </Style>

    </Window.Resources>

    <StackPanel>       

        <Button Name="button1" Click="button_click">Button1</Button>

        <Button Name="button2" Click="button_click">Button2</Button>


        <Button Name="button3" Click="button3_click">Button3</Button>

    </StackPanel>

</Window>


[MainWindow.xaml.cs]

using System.Windows;

using System.Windows.Controls;


namespace WpfApp6

{

    public partial class MainWindow : Window

    {

        public MainWindow()

        {

            InitializeComponent();

        }

        public void EventSetter_Click(object sender, RoutedEventArgs e)

        {

            Button b = e.Source as Button;

            b.Background = new SolidColorBrush(Colors.Red);

        }

        public void button_click(object sender, RoutedEventArgs e)

        {

            Button btn = e.Source as Button;

            MessageBox.Show(btn.Content + " has been clicked", Title);

        }

        public void button3_click(object sender, RoutedEventArgs e)

        {

            Button btn = e.Source as Button;

            MessageBox.Show(btn.Content + " has been clicked", Title);

            e.Handled = true;  //이벤트 라우팅 종료

        }

    }

}



https://www.youtube.com/watch?v=MGOb9QXi6So&list=PLxU-iZCqT52Cmj47aKB1T-SxI33YL7rYS&index=5 

https://www.youtube.com/watch?v=KfY6DqWtcqs&list=PLxU-iZCqT52Cmj47aKB1T-SxI33YL7rYS&index=4 

#WPFStyle, #EventSetter, #e.handled, #이벤트라우팅, #WPF동영상, #WPF, #WPF교육, #WPF강좌, #WPF강의, #WPF학원, WPFStyle, EventSetter, e.handled, 이벤트라우팅, WPF동영상, WPF, WPF교육, WPF강좌, WPF강의, WPF학원,  

2021년 12월 18일 토요일

(WPF동영상, WPF교육, WPF학원교육, WPF학원)데이터 바인딩(Data Binding) 이란?

 











(WPF동영상)데이터 바인딩(Data Binding) 이란?

  • 데이터 바인딩이란 “컨트롤 or 엘리먼트를 데이터에 연결시키는 기술”이다. 
  • 예문

//소스객체

<TextBox Name="txt1" Text="{Binding Mode=OneWay}" />


//타겟객체

<TextBox Name="txt2"  

Text="{Binding Source={x:Reference txt1},Path=Text}"/>

  • 데이터 바인딩은 소스와 타겟이 필요하며 일반적으로 소스는 데이터(ViewModel)이고 타겟은 컨트롤 입니다. 하지만 어느 경우엔 소스와 타겟 둘다 컨트롤이 될수가 있어 구분이 모호할 때도 있습니다. 또 어떤 경우에는 반대로 타겟이 소스에게 데이터를 전달하기도 합니다.
  • 모든 바인딩에는 소스 객체, 소스 속성, 타겟 객체 및 타겟 속성이 있습니다.
  • 타겟 객체는 바인딩 할 속성, 즉 데이터를 렌더링하는 UI 컨트롤을 소유하는 객체이며 소스 객체는 Binding Source속성 또는 ViewModel 클래스인 경우 DataContext 속성으로 지정하면 됩니다.
  • Binding.Source 속성을 통해 지정되는 원본 개체없이 정의 된 바인딩은 대상 개체의 DataContext를 원본으로 사용한다. 
  • DataContext 값은 한 컨트롤에서 다른 컨트롤로 비주얼 트리 아래로 상속되는데, 하위 객체에서 사용가능 합니다.
  • 데이터 바인딩은 이벤트 핸들러를 대체할 수 있는데 이는 C#코드를 줄이는 역할을 합니다. XAML에서 정의된 데이터 바인딩은 C# 코드 비하인드 파일에서 이벤트 핸들러를 정의할 필요가 없으며 코드 비하인드 파일 자체가 필요 없는 경우도 있습니다.
  • 컨트롤은 데이터를 사용자에게 보여주는 것과 사용자가 데이터를 변경할 수 있게 해주는 두 가지 기능을 제공합니다. 최근 컨트롤과 데이터 사이의 많은 반복 작업들이 단순화 되면서 CheckBox를 Boolean 변수로 바인딩하고 사용자가 작업이 끝난 후 Boolean 변수를 다시 CheckBox 값으로 바인딩하는 코드들을 만들어야 했는데 아래처럼 CheckBox와 Bool 변수 사이를 데이터바인딩을 이용하게 간단하게 처리할 수 있습니다.
  • 예문.

[MainWindow.xaml]

<StackPanel Orientation="Vertical" Margin="20" >

        <Label Content="Which city do you love?"/>

        <CheckBox Content="SEOUL" IsChecked="{Binding Seoul}"/>

        <CheckBox Content="JEJOO" IsChecked="{Binding Jejoo}"/>

        <CheckBox Content="INCHEON" IsChecked="{Binding Incheon}"/>

        <Button Content="제출" Click="Sumit_Click"/>

</StackPanel>


[MainWindow.xaml.cs]

public partial class MainWindow : Window

{

//UI 컨트롤에서 바인딩으로 사용할 소스 속성들

public bool Seoul { get; set; }

public bool Jejoo { get; set; }

public bool Incheon { get; set; }


public MainWindow()

{

      this.InitializeComponent();

      //바인딩의 소스객체, UI컨트롤에서 별도의 소스 지정없이 사용가능

      //Window의 하위객체에서 소스 속성으로 사용가능

      this.DataContext = this; 

}


//버튼의 클릭 이벤트 핸들러

private void Sumit_Click(object sender, RoutedEventArgs e)

{

      MessageBox.Show(string.Format("SEOUL: {0}, JEJOO: {1}, INCHEON: {2}", Seoul, Jejoo, Incheon));

}


}




  • 다음은 TextBox간의 단방향 데이터 바인딩 예문을 살펴보자.
  • 아래 예문은 별도의 C#코드는 필요 없다. txt1이 소스 객체가 되고 txt2가 타겟 객체가 되어 소스의 Text 속성의 값을 타겟 txt2의 Text 속성에 바인딩 시킨다.

<StackPanel Orientation="Vertical" Margin="20" >

        <TextBox Name="txt1"  Text="{Binding Mode=OneWay}" />

        <TextBox Name="txt2"  

Text="{Binding Source={x:Reference txt1},Path=Text}"/>

</StackPanel>

위쪽 TextBox에 값을 입력하며 아래쪽 TextBox에 자동 입력된다.

  • 위 코드를 수정하여 양방향바인딩으로 만들어보자.
  • 위쪽 TextBox에서 입력을 하면 아래에 자동 반영 되지만, 아래쪽 TextBox에서 입력을 하면 바로 반영은 안되고 포커스를 잃는경우에만 하는 경우에 상단의 TextBox에 반영된다. (양방향에서 타겟이 소스를 UPDATE하는 타이밍은 UpdateSourceTrigger 속성으로 지정하는데 대부분의 의존 속성 기본값이 PropertyChanged인 반면 Text 속성은 기본값이 LostFocus 입니다.)

<TextBox Name="txt1"  Text="{Binding Path=Text, Mode=TwoWay}" />

        <TextBox Name="txt2"  

Text="{Binding Source={x:Reference txt1},Path=Text}"/>


최종적으로 아래와 같이 UpdateSourceTrigger 절을 타겟객체쪽에 추가하자. 소스를 갱신할 타이밍을 지정하는 곳이고 Text 속성인 경우 기본값은 포커스를 잃을 때(LostFocus)이다.

<TextBox Name="txt1"  Text="{Binding Path=Text, Mode=TwoWay}" />

<TextBox Name="txt2"  

Text="{Binding Source={x:Reference txt1},Path=Text, 

UpdateSourceTrigger =PropertyChanged}"/>

다른 예문을 살펴보자.

public partial class MainWindow {

public MainWindow()

{

  InitializeComponent();


  // create a model object

  _viewmodel = new MyViewModel()

  {

    Date = new DateTime(201171),

    Title = "WPF User Group"

  };


  // bind the Date to the UI

  this.DataContext = _viewmodel;

}

}


<Grid x:Name="LayoutRoot" Background="White">

  ...


  <TextBlock Text="Name:"

              Grid.Row="1"/>

  <TextBox Text="{Binding Path=Title, Mode=TwoWay}"

           Grid.Row="1" Grid.Column="1"/>


  <TextBlock Text="Date:"

              Grid.Row="2"/>

  <sdk:DatePicker SelectedDate="{Binding Path=Date, Mode=TwoWay}"

                  Grid.Row="2" Grid.Column="1"/>

</Grid>


#WPF데이터바인딩, #데이터바인딩, #DataBinding, #WPF교육, #WPF강의, #WPF동영상, #WPF학원,WPF데이터바인딩, 데이터바인딩, DataBinding, WPF교육, WPF강의, WPF동영상, WPF학원


WPF 캔버스(WPF Canvas), WPF동영상교육, WPF교육, WPF학원

 















WPF 캔버스(WPF Canvas)

  • 엘리먼트가 어디에 위치할지 좌표로 지정하는 전통적인 방법이다.
  • WPF의 다른 부분과 마찬가지로 이 좌표계도 좌측 상단을 기준으로 1/96인치의 장치 독립적인 단위를 사용한다.
  • 엘리먼트에는 X, Y, Left, Top과 같은 프로퍼티는 없으며 Canvas 패널을 사용할 때는 Canvas.SetLeft, Canvas.SetTop과 같은 정적메소드를 사용하여 자식엘리먼트의 위치를 지정한다. DockPanel의 SetDock 메소드처럼 SetLeft, SetTop은 Canvas 클래스에 정의되어 있는 첨부 프로퍼티와 연결되어 있다.
  • Canvas의 우측하단을 기준으로 자식 엘리먼트의 오른쪽 또는 하단의 위치를 지정하려면 Canvas.SetRight, Canvas.SetBottom을 사용한다.
  • 몇 가지 Shape 클래스(Line, Path, Polygon, PolyLine등)에는 이미 좌표 데이터가 저장되어 있는데 이런 엘리먼트를 Canvas 패널의 Children 컬렉션에 추가하고 좌표를 지정하지 않으면 엘리먼트에 있는 좌표 데이터를 이용하여 위치를 잡는다.
  • 컨트롤과 같은 엘리먼트는 Canvas 위에서 적절하게 크기가 조절되지만 Rectangle, Ellipse 엘리먼트는 그렇지 않으므로 명시적으로 Width, Height를 대입하는 것이 좋고 Canvas 패널 자체의 Width, Height 프로퍼티에도 값을 지정하는 것이 일반적이다.
  • Example Canvas XAML Code

<Window x:Class="WpfApplication1.MainWindow"

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

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

        Title="Canvas Test1" Height="300" Width="300">

    <Canvas>

        <Button Canvas.Left="40">Top left</Button>

        <Button Canvas.Right="80">Top right</Button>

        <Label Content="Label Text" Canvas.Bottom="110" Canvas.Left="110"/>

        <Button Canvas.Left="20" Canvas.Bottom="10">Bottom left</Button>

        <Button Canvas.Right="40" Canvas.Bottom="10">Bottom right</Button>

    </Canvas>

</Window>

  • 비주얼 스튜디오 -> WPF 응용프로그램 -> CanvasTest1
  • MainWindow.xaml

<Window x:Class="CanvasTest1.MainWindow"

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

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

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

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

        xmlns:local="clr-namespace:CanvasTest1"

        mc:Ignorable="d"

        Title="Canvas Test1" Height="350" Width="525"

        Loaded="WindowOnLoaded">

    <Grid>

        <Canvas HorizontalAlignment="Left" Height="319" Margin="0"

VerticalAlignment="Top" Width="517"

Name="canvas1"/>

    </Grid>

</Window>

  • MainWindow.xaml.cs

using System.Collections.Generic;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Media;

using System.Windows.Shapes;


namespace CanvasTest1

{

    class MyRectangle

    {

        public int Width { getset; }

        public int Height { getset; }

        public int Left { getset; }

        public int Top { getset; }

        public SolidColorBrush Color { getset; }

    }


    public partial class MainWindow : Window

    {

        public MainWindow()

        {

            InitializeComponent();

        }


        private void WindowOnLoaded(object sender, RoutedEventArgs e)

        {

            // MyRectangle을 담기위한 ArrayList

            List<MyRectangle> rects = new List<MyRectangle>();


            // MyRectangle을 담는다.

            rects.Add(new MyRectangle()

            {

                Width = 100,

                Height = 100,

                Left = 0,

                Top = 0,

                Color = Brushes.MediumSpringGreen

            });

            rects.Add(new MyRectangle()

            {

                Width = 50,

                Height = 50,

                Left = 100,

                Top = 100,

                Color = Brushes.YellowGreen

            });

            rects.Add(new MyRectangle()

            {

                Width = 25,

                Height = 25,

                Left = 150,

                Top = 150,

                Color = Brushes.PowderBlue

            });


            foreach (MyRectangle rect in rects)

            {

                // Rectangle 객체생성

                Rectangle r = new Rectangle();

                r.Width = rect.Width;

                r.Height = rect.Height;

                r.Fill = rect.Color;


                // Canvas내 위치를 기본적인 MyRectangle의 위치로 설정

                Canvas.SetLeft(r, rect.Left);

                Canvas.SetTop(r, rect.Top);


                // Canvas에 추가

                canvas1.Children.Add(r);

            }

        }

    }

}

  • 실행결과


#WPF캔버스, #WPFCanvas, #WPF강좌, #WPF교육, #WPF강의, #WPF학원, #닷넷학원, #시샵교육, #닷넷교육, WPF캔버스, WPFCanvas, WPF강좌, WPF교육, WPF강의, WPF학원, 닷넷학원, 시샵교육, 닷넷교육,



(C#교육동영상)C# ADO.NET 실습 ODP.NET/ODAC 설치 오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원

  (C#교육동영상)C# ADO.NET 실습  ODP.NET/ODAC 설치  오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원 https://www.youtube.com/watch?v=qIPU85yAlzc&list=PLxU-i...