본문으로 바로가기

C# Winform WPF #4

category C# WPF 2020. 6. 25. 11:10

데이터 바인딩

  • 현재의 거의 모든 앱은 데이터 중심.데이터 저장소(데이터베이스,파일시스템,클라우드 등)에서 데이터를 가져와 사용자에게 표시,사용자가 변경,업데이트 된 내용을 저장소에 다시 저장
  • 바인딩의 두가지 디자인 패턴

    - Early(static)Binding­ (전통적) 함수호출에서 실행될 함수나 프로시저를 컴파일 시점에 결정하는 것

    - Lazy(dynamic) Binding ­ (객체지향적)메시지에 응답하기 위해 실행될 메서드를 실행시점에 결정하는 것

    - 적절하게 사용될 경우 프로그램의 운영 차원의 효율성

  • 데이터를 표시하는 컨트롤 -> 컨트롤 속성에 변수 할당 -> 사용자는 이 컨트롤로 데이터 확인 -> 변경 후 이벤트처리로 원 변수 값을 변경 -> 수정된 데이터를 저장소로 이동
<TextBox Text="{BindingSpeed,ElementName=c}"/>

Binding 키워드

<TextBox Text="{BindingSpeed}"/>

명시적 구문과 동일

<TextBox Text="{BindingPath=Speed}"/>

Binding구문내 속성

  • ElementName ­ 상태 표시
  • Source­ 원본 데이터 객체를 리소스로 정의할 때
  • someList 컨트롤의 높이가 표시, TextBox 컨트롤에 새 값을 입력하면 someList의 높이가 변경됨
<TextBox Text="{BindingSource={StaticResource someList},Path=Height}"/>

 

예제 분석(xaml 소스)

<StackPanel>
  <Slider x:Name="slider" Maximum="100"
  	  Value="10"/>
  <ProgressBar Value="{Binding Value, ElementName=slider}" Height="20"/>
  <TextBlock Text="{Binding Value, ElementName=slider}" TextAlignment="Center"/>
</StackPanel>

실행화면

바인딩 모드

업데이트 시
모드 대상 변경 값 변경
TwoWay Yes Yes
OneWay No Yes
OneWayToSource Yes  
OneTime No No

모드 변경 시

{Binding Path=Speed, Mode=TwoWay}

데이터 컨텍스트

  • 그룹화된 데이터들은 동일한 데이터 객체의 데이터 사용
  • DRY(Don’tRepeatYourself)
  • 바인딩에 소스 데이터 객체를 지정하지 않으면 소스가 현재 데이터 컨텍스트로 간주
<StackPanel DataContext="...">
  <TextBox Text="{Binding Name}"/>
  <Label Content="{Binding SSN}"/>
</StackPanel>
  • 코드 비하인드에서 할당 가능
this.DataContext =...;

 

변환기

  • 데이터 바인딩 시 유형을 객체 유형을 변환
  • IValueConverter 인터페이스를 상속해 작성하는 단순 클래스

    - Convert­ 표준 메서드

    - ConvertBack ­ 양방향 데이터 바인딩에만 사용

 

namespace Maths
{
  public class TwiceConverter :IValueConverter
   {
      public object Convert(object value,TypetargetType,object parameter,CultureInfo culture)
      {
        return ((int)value)*2;
      }
    
      public object ConvertBack(object value,TypetargetType,object parameter,CultureInfo culture)
      {
        //thrownewNotImplementedException();
        return null;
      }
   }
}

xaml에서 사용시 아래와 같이 사용

<Page x:Class="BikeShop.Test"
    xmlns:c="clr-namespace:Maths">
  <Page.Resources>
    <c:TwiceConverter x:Key="twiceConv"/>
  </Page.Resources>
<Grid>
    <TextBlock value="{Binding Speed, Converter={StaticResource twiceConv}}"/>

데이터 컬렉션

목록 컨트롤을 사용하는 컬렉션 표시 ­- Ienumerable(Array,Stack,List…)를 사용하는 ItemsSource

private void Inits()
{
    //myCar.Color =Colors.Blue;
    var cars=new List<Car>();
    for (int i=0;i<10;i++)
    {
      cars.Add(new Car()
      {
         Speed=i *10
       });
    }
   this.DataContext =cars;
}

xaml

<ListBox ItemsSource="{Binding}"/>

데이터 바인딩

목록 컨트롤 사용자 정의

- BusinessLogic.Car 만 나오는 이유 ­ WPF가 각 Car클래스의 인스턴스를 표시하는 방법을 모르기 때문에 각 인스턴스의    ToString 메서드를 호출

 

- 방법

  • ItemsPanel은 요소를 배치하는 방법을 설명
  • ItemTemplate은 각 요소에 대해 반복이 필요한 템플릿을 제공 ­ 각 목록 항목에 대해 반복되는 DataTemplate 이어야 함
  • ItemContainerStyle은 항목을 선택하거나 마우스를 올릴 때 동작 방법을 설명
  • Template은 컨트롤 자체를 렌더링 하는 방법을 설명

- 해결

<ListBox ItemsSource="{Binding}">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding Speed}"/>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

실행화면

목록 컨트롤 사용자 정의

텍스트 외에도 표현 가능

<ListBox ItemsSource="{Binding}">
  <ListBox.ItemTemplate>
    <ItemContainerTemplate>
      <StackPanel>
        <TextBlock Text="Speed"/>
        <TextBox Text="{Binding Speed}"/>
        <Slider Value="{Binding Speed}" Maximum="100"/>
        <TextBlock Text="Color"/>
        <Border Height="10">
          <Border.Background>
            <SolidColorBrush Color="{Binding Color}"/>
          </Border.Background>
        </Border>
        <TextBox Text="{Binding Color}"/>
      </StackPanel>
    </ItemContainerTemplate>
  </ListBox.ItemTemplate>
</ListBox>

실행화면
Tutorial 4

데이터 객체 메시지 표시

  • 프로젝트 컨텍스트 메뉴 >추가 >기존 항목

chat.png, Talk.cs 파일 선택

 

  • Discussion.xaml 파일 오픈

Page요소에 추가

xmlns:data="clr-namespace:BikeShop"

Grid 요소에 포함된 ListBox 선언 찾아서 수정

<ListBox Grid.ColumnSpan="2" Margin="5">
  <ListBox.ItemsSource>
    <data:Talk />
  </ListBox.ItemsSource>
</ListBox>

데이터 객체 메시지 표시

ListBox 선언을 ItemTemplate 속성으로 대체

<ListBox Grid.ColumnSpan="2" Margin="5">
  <ListBox.ItemsSource>
    <data:Talk />
  </ListBox.ItemsSource>
  <ListBox.ItemTemplate>
    <DataTemplate>
      <StackPanel>
        <StackPanel Orientation="Horizontal">
          <Image Source="chat.png" Width="20"/>
          <TextBlock Text="{Binding Sender}"/>
        </StackPanel>
        <TextBlock Text="{Binding Content}" Margin="20,0,0,0" TextWrapping="Wrap"/>
      </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

실행화면

 

'C# WPF' 카테고리의 다른 글

C# Winform WPF #5  (0) 2020.06.26
C# Winform WPF #3  (0) 2020.06.23
C# Winform WPF #2  (0) 2020.06.23
C# Winform WPF #1  (0) 2020.06.23