14. 데이터 귀속 관련 예

73716 단어 데이터 바인딩
1. 일반 CLR 유형의 단일 객체를 Source로 지정: 포함.NET Framework 자체 객체 및 사용자 정의 유형의 객체
유형이 INotifyPropertyChanged 인터페이스를 구현한 경우 속성의 set 문에서PropertyChanged 이벤트를 발생시켜 Binding 데이터가 업데이트되었음을 알릴 수 있습니다.
using System.ComponentModel;



namespace _SampleDataBinding

{

    class Person:INotifyPropertyChanged

    {

        public event PropertyChangedEventHandler PropertyChanged;



        private string _personName= string.Empty;



        public string PersonName 

        {

            get { return this._personName; }

            set { this._personName = value;

                if (PropertyChanged != null)

                {

                    PropertyChanged.Invoke(this,new PropertyChangedEventArgs(PersonName));

                }

            }

        }

    }

}
<StackPanel>

        <TextBox Name="TxtTest1" Text="{Binding Source={StaticResource MyPerson}, Path=PersonName}"></TextBox>

        <Button Name="BtnTest" Height="36" Click="BtnTest_OnClick"> </Button>

</StackPanel>
        private void BtnTest_OnClick(object sender, RoutedEventArgs e)

        {

            Person per=new Person();

            per.PersonName = "";

        }

2. 일반 CLR 집합 유형의 대상을Source로 지정한다. 수조,List,ObservableCollection 등 집합 유형을 포함한다.
    class Student

    {

        public int Id { get; set; }

        public string Name { get; set; }

        public int Age { get; set; }

    }
    <StackPanel Background="LightBlue">

        <TextBlock Text=" :" FontWeight="Bold" Margin="5" FontSize="16"></TextBlock>

        <TextBox x:Name="TxtBoxId" Margin="5" Height="36"></TextBox>

        <TextBlock Text=" :" FontSize="16" FontWeight="Bold" Margin="5"></TextBlock>

        <ListBox x:Name="ListBoxStudents" Height="195" Margin="5">

        </ListBox>

    </StackPanel>
            // 

            List<Student> stuList =new List<Student> ( )

            {

                new Student(){Id = 001,Name = "Apple",Age = 12},

                new Student(){Id = 002,Name = "Banana",Age = 13},

                new Student(){Id = 003,Name = "Cocoa",Age = 14},

                new Student(){Id = 004,Name = "Dog",Age = 15},

                new Student(){Id = 005,Name = "Func",Age = 16},

                new Student(){Id = 006,Name = "Great",Age = 17}

            };

            // ListBox Binding

            this.ListBoxStudents.ItemsSource = stuList;

            this.ListBoxStudents.DisplayMemberPath = "Name";

            // TextBox Binding

            Binding binding=new Binding("SelectedItem.Id"){Source = this.ListBoxStudents};

            this.TxtBoxId.SetBinding(TextBox.TextProperty, binding);

XAML에 바인딩 코드를 쓰면 어떻게 써야 합니까?
<TextBox x:Name="TxtBoxId"  Text="{Binding ElementName=ListBoxStudents,Path=SelectedItem.Id}"></TextBox>

Path를 쓸 때 SelectedItem.Id, 여기서Id는 힌트를 주지 않으니 억지로 써야 한다.
XAML에 직접 연결해 보려고 했는데 반나절 동안 성공하지 못했습니다. 찌질한 고양이에게 가르침을 청한 후에 해결 방안을 제시했습니다. 다음은 코드입니다.
    public class Student

    {

        public int StudentNum { get; set; }

        public string StudentName { get; set; }

        public int StudentAge { get; set; }

    }
    public class Data

    {

        private List<Student> _studentsList; 

        public List<Student> StudentsList

        {

            get { return _studentsList; } 

            set { _studentsList = value; }

        }

    }
    {

        public Data myData;

        private List<Student> studentsList; 

        public MainWindow ( )

        {

            InitializeComponent ( );

            myData=new Data();

            // 



            studentsList =new List<Student> ( )

            {

                new Student(){StudentNum = 001,StudentName  = "Apple",StudentAge = 12},

                new Student(){StudentNum = 002,StudentName = "Banana",StudentAge = 13},

                new Student(){StudentNum = 003,StudentName = "Cocoa",StudentAge = 14},

                new Student(){StudentNum = 004,StudentName = "Dog",StudentAge = 15},

                new Student(){StudentNum = 005,StudentName = "Func",StudentAge = 16},

                new Student(){StudentNum = 006,StudentName = "Great",StudentAge = 17}

            };

            myData.StudentsList = studentsList;

            this.DataContext = myData;

        }

다시 한 번 예를 써 보아라
        private List<Student> stuList; 

        public MainWindow ( )

        {

            InitializeComponent ( );

            stuList=new List<Student>()

                {

                    new Student(){StudentId = 001,StudentName = " ",StudentAge = 12},

                    new Student(){StudentId = 002,StudentName = " ",StudentAge = 13},

                    new Student(){StudentId = 003,StudentName = " ",StudentAge = 14},

                    new Student(){StudentId = 004,StudentName = " ",StudentAge = 15},

                    new Student(){StudentId = 005,StudentName = " ",StudentAge = 16}

                };

            this.listBoxStudents.ItemsSource = stuList;

        }
        <ListBox x:Name="listBoxStudents" Height="300" Margin="5" >

            <ListBox.ItemTemplate>

                <DataTemplate>

                    <StackPanel Orientation="Horizontal">

                        <TextBlock Text="{Binding Path=StudentId}" Width="30"></TextBlock>

                        <TextBlock Text="{Binding Path=StudentName}" Width="60"></TextBlock>

                        <TextBlock Text="{Binding Path=StudentAge}" Width="30"></TextBlock>

                    </StackPanel>

                </DataTemplate>

            </ListBox.ItemTemplate>

        </ListBox>

만약 위의 이 예에서 또 몇 개의 데이터가 나오면 어떻게 합니까?WPF가 제시한 해결 방안은 집합 유형을 목록 공간으로 하는 ItemSource를 사용할 때 일반적으로 Observable Collection
List를 대체합니다. Observable Collection이INotify Collection Changed와INotify Property Changed 인터페이스를 실현하여 집합의 변화를 즉시 알릴 수 있습니다.
목록 컨트롤, 이 백뇌환이 바로 표시됩니다.
            private ObservableCollection<Student> newStuList;



            newStuList=new ObservableCollection<Student>()

                {

                    new Student(){StudentId = 001,StudentName = " ",StudentAge = 12},

                    new Student(){StudentId = 002,StudentName = " ",StudentAge = 13},

                    new Student(){StudentId = 003,StudentName = " ",StudentAge = 14},

                    new Student(){StudentId = 004,StudentName = " ",StudentAge = 15},

                    new Student(){StudentId = 005,StudentName = " ",StudentAge = 16}

                };



            this.listBoxStudents.ItemsSource = newStuList;





        private void BtnTest_OnClick(object sender, RoutedEventArgs e)

        {

            newStuList.Add(new Student(){StudentId = 006,StudentName = " ",StudentAge = 17});



        }

3. ElementName을 Source로 지정
        <TextBox Name="TxtBox" BorderBrush="DeepSkyBlue" Height="35" Margin="5" 
          Text
="{Binding ElementName=SliderTest,Path=Value,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox> <Slider Name="SliderTest" Margin="5" BorderBrush="DimGray" Maximum="100" Minimum="0"></Slider>

Mode는 데이터가 흐르는 방향을 나타낸다. 그 값인 TwoWay는 데이터가 양방향으로 흐르는 것을 의미한다. 슬라이더 컨트롤러의 값은 TextBox로 업데이트할 수 있고 TextBox의 값도 슬라이더로 업데이트할 수 있다. 이 기능을 실현하려면 수정이 필요하다.
UpdateSourceTrigger 속성의 값입니다. TextBox의 이 속성 값은 기본값인Default, 즉 LostFocus이기 때문에 초점을 잃은 후에야 변경됩니다.
4、Path의 귀속 없음
    <StackPanel>

        <StackPanel.Resources>

            <sys:String x:Key="myString"> Path , </sys:String>

        </StackPanel.Resources>

        <TextBlock Name="TextBlockTest" Text="{Binding Source={StaticResource myString} }"></TextBlock>

    </StackPanel>

C#의 동급 코드
            string a = "dafagagdfgghh";

            this.TextBoxTest.SetBinding(TextBox.TextProperty, new Binding(".") {Source = a});

앞의 예는 대부분 단일 CLR 유형의 대상을 Binding의 Source로 지정하는데 방법은 두 가지가 있다. - Banding.Source 속성 또는 객체의 Name 값을 Binding에 지정합니다.ElementName.
5, Source 바인딩 없음 - DataContext를 Binding 소스로 사용
DataContext 속성은 FrameworkElement 클래스에 정의됩니다. 이 클래스는 WPF 컨트롤의 기본 클래스입니다. 이것은 WPF 공간(용기 컨트롤 포함)이 모두 이런 속성을 갖추고 있음을 의미합니다.앞에서 설명한 바와 같이 WPF의 UI 레이아웃은 트리 구조이며 이 트리의 각 노드에는 DataContext가 있습니다.
Binding은 자신의 Path만 알고 자신의 Source를 알지 못할 때 UI 요소 트리를 따라 나무의 뿌리를 찾아간다. 결점을 지나갈 때마다 이 결점의 DataContext가Path가 지정한 속성을 가지고 있는지 확인해야 한다.있다면 이 대상을 자신의 Source로 삼아라.없으면 계속 찾아라.만약 나무의 뿌리에 이르러도 아직 찾지 못한다면 이 빙딩은 Source가 없기 때문에 데이터를 얻지 못할 것이다.
eg1:
    <Grid DataContext=" ">

        <Grid>

            <StackPanel>

                <Button x:Name="BtnTest" Content=" " Click="BtnTest_OnClick"></Button>

            </StackPanel>

        </Grid>

    </Grid>
        private void BtnTest_OnClick(object sender, RoutedEventArgs e)

        {

            MessageBox.Show(BtnTest.DataContext.ToString());

        }

eg2:
    <Grid DataContext=" ">

        <Grid>

            <StackPanel>

                <Button x:Name="BtnTest" Content=" " Click="BtnTest_OnClick"></Button>

                <TextBox x:Name="TextBoxtTest" Text="{Binding Path=.}"></TextBox>

            </StackPanel>

        </Grid>

    </Grid>

eg3:
    public partial class Student

    {

        public int StuId { get; set; }

        public string StuName { get; set; }

        public int StuAge { get; set; }

    }
    <StackPanel>

        <StackPanel.DataContext>

           <local:Student StuId="001" StuName=" " StuAge="100"></local:Student>

        </StackPanel.DataContext>

        <TextBox Text="{Binding StuId}"></TextBox>

        <TextBox Text="{Binding StuName}"></TextBox>

        <TextBox Text="{Binding StuAge}"></TextBox>

    </StackPanel>

eg4: MVVM 모드 해결 회색 고양이 솔루션
    class StudentViewModel

    {

        public Student stu { get; set; }



        public StudentViewModel()

        {

            stu=new Student()

                {

                    StuId = 2,

                    StuName = " ",

                    StuAge = 100

                };

        }

    }
    public partial class MainWindow : Window

    {

        public MainWindow ( )

        {

            InitializeComponent ( );

            this.DataContext = new StudentViewModel();

        }

    }
    <StackPanel DataContext="{Binding stu}">

        <TextBox Text="{Binding StuId}"></TextBox>

        <TextBox Text="{Binding StuName}"></TextBox>

        <TextBox Text="{Binding StuAge}"></TextBox>

    </StackPanel>

6. XML 데이터를 Binding 데이터 소스로 사용
    <Window.Resources>

        <XmlDataProvider x:Key="xdp" XPath="FileSystem/Folder">

            <x:XData>

                <FileSystem xmlns="">

                    <Folder Name="A">

                        <Folder Name="BooksA">

                            <Folder Name="Programming">

                                <Folder Name="Windows">

                                    <Folder Name="WCF"/>

                                    <Folder Name="MFC"/>

                                    <Folder Name="Delphi"/>

                                </Folder>

                            </Folder>

                            <Folder Name="Tools">

                                <Folder Name="Development"/>

                                <Folder Name="Designment"/>

                                <Folder Name="Players"/>

                            </Folder>

                            <Folder Name="Tools">

                                <Folder Name="Development"/>

                                <Folder Name="Designment"/>

                                <Folder Name="Players"/>

                            </Folder>

                        </Folder>

                        <Folder Name="BooksB">

                            <Folder Name="Programming">

                                <Folder Name="Windows">

                                    <Folder Name="WCF"/>

                                    <Folder Name="MFC"/>

                                    <Folder Name="Delphi"/>

                                </Folder>

                            </Folder>

                            <Folder Name="Tools">

                                <Folder Name="Development"/>

                                <Folder Name="Designment"/>

                                <Folder Name="Players"/>

                            </Folder>

                            <Folder Name="Tools">

                                <Folder Name="Development"/>

                                <Folder Name="Designment"/>

                                <Folder Name="Players"/>

                            </Folder>

                        </Folder>

                    </Folder>

                </FileSystem>

            </x:XData>

        </XmlDataProvider>

    </Window.Resources>

    <Grid>

        <TreeView ItemsSource="{Binding Source={StaticResource xdp}}">

            <TreeView.ItemTemplate>

                <HierarchicalDataTemplate ItemsSource="{Binding XPath=Folder}">

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

                </HierarchicalDataTemplate>

            </TreeView.ItemTemplate>

        </TreeView>

    </Grid>

XmlDataProvider를 XAML 코드에 직접 쓰면 XML 데이터는 ... 태그
XML 파일을 별도로 쓰는 경우에는 어떻게 합니까?
<?xml version="1.0" encoding="utf-8" ?>

<StudentList>

  <Student Id="1">

    <Name>Trim</Name>

  </Student>

  <Student Id="2">

    <Name>Tom</Name>

  </Student>

  <Student Id="3">

    <Name>Jim</Name>

  </Student>

  <Student Id="4">

    <Name>Aim</Name>

  </Student>

</StudentList>
    <StackPanel Background="DeepSkyBlue">

        <ListView x:Name="listViewTest" Height="200">

            <ListView.View>

                <GridView>

                    <GridViewColumn Header="Id" Width="80" DisplayMemberBinding="{Binding XPath=@Id}"></GridViewColumn>

                    <GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding XPath=Name}"></GridViewColumn>

                </GridView>

            </ListView.View>

        </ListView>

        <Button Height="36" Click="ButtonBase_OnClick">XML </Button>

        <Button Height="36" Margin="0,5,0,0" Name="BtnTest" Click="BtnTest_OnClick"> </Button>

    </StackPanel>
        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)

        {

            XmlDocument doc=new XmlDocument();

            doc.Load(@"./StudentsData.xml");

            XmlDataProvider xdp=new XmlDataProvider();

            xdp.Document = doc;

            xdp.XPath = @"/StudentList/Student";



            this.listViewTest.DataContext = xdp;

            this.listViewTest.SetBinding(ListView.ItemsSourceProperty, new Binding());

        }



        private void BtnTest_OnClick(object sender, RoutedEventArgs e)

        {

            XmlDataProvider xdp=new XmlDataProvider();

            xdp.Source = new Uri ( @"E:\C#\WPF\ \08 XML Binding \bin\Debug\StudentsData.xml" );

            xdp.XPath = @"/StudentList/Student";



            this.listViewTest.DataContext = xdp;

            this.listViewTest.SetBinding(ListView.ItemsSourceProperty, new Binding());

        }

두 가지 다른 읽기 방식
7. LINQ 검색 결과를 Binding의 소스로 사용
        <ListView x:Name="listViewStudents" Height="143" Margin="5">

            <ListView.View>

                <GridView>

                    <GridViewColumn Header="Id" Width="60" DisplayMemberBinding="{Binding Id}"></GridViewColumn>

                    <GridViewColumn Header="Name" Width="100" DisplayMemberBinding="{Binding Name}"></GridViewColumn>

                    <GridViewColumn Header="Age" Width="80" DisplayMemberBinding="{Binding Age}"></GridViewColumn>

                </GridView>

            </ListView.View>

        </ListView>
        private void BtnTest_OnClick(object sender, RoutedEventArgs e)

        {

            List<Student> stuList=new List<Student>()

                {

                    new Student(){Id = 0,Name = "Tim",Age=10},

                    new Student(){Id = 1,Name = "Tom",Age = 11},

                    new Student(){Id = 2,Name = "Tony",Age = 12},

                    new Student(){Id = 3,Name = "Jim",Age = 13}

                };

            this.listViewStudents.ItemsSource = from student in stuList

                                                where student.Name.StartsWith("T")

                                                select student;



        }

8. ObjectDataProvider 대상을 Binding의 Source로 사용한다. 대상을 데이터 원본으로 Binding에 제공하는 것이다.
이상적인 상황에서 상위 프로그래머는 클래스 ishejihao, 사용 속성을 사용하여 데이터를 폭로하고 하위 프로그래머는 이런 종류의 실례를 Binding의 Source로 하고 속성을 Binding의 Path로 이런 종류를 소비한다.그러나 하나의 유형idea가 모든 데이터를 속성으로 노출할 수 있다는 것을 보장하기 어렵다. 예를 들어 우리가 필요로 하는 데이터가 방법의 반환값일 수도 있다.한편, 베이스 클래스를 재설계하는 위험과 비용이 비교적 높고 블랙박스 인용 라이브러리의 경우 우리는 이미 컴파일된 클래스를 변경할 수 없다. 이럴 때 ObjectDataProvider를 사용하여 Binding의 원본 데이터 대상으로 포장해야 한다. 
    class Calculator

    {

        public string Add(string str1, string str2)

        {

            double x,y,z = 0;

            if (double.TryParse(str1, out x) && double.TryParse(str2, out y))

            {

                z = x + y;

                return z.ToString();

            }

            else

            {

                return "Inpurt Error!";

            }

        }

    }
        private void BtnTest_OnClick(object sender, RoutedEventArgs e)

        {

            ObjectDataProvider odp=new ObjectDataProvider();

            odp.ObjectInstance = new Calculator();

            odp.MethodName = "Add";

            odp.MethodParameters.Add("100");

            odp.MethodParameters.Add("200");

            MessageBox.Show(odp.Data.ToString());

        }

XAML에서 구현
    public partial class MainWindow : Window

    {

        public MainWindow ( )

        {

            InitializeComponent ( );

            this.SetBinding();

        }



        private void SetBinding()

        {

            // ObjectDataProvider 

            ObjectDataProvider odp=new ObjectDataProvider();

            odp.ObjectInstance = new Calculator();

            odp.MethodName = "Add";

            odp.MethodParameters.Add("10");

            odp.MethodParameters.Add("10");



            // ObjectDataProvider Source Binding

            Binding bindingToStr1=new Binding("MethodParameters[0]")

                {

                    Source = odp,

                    BindsDirectlyToSource=true,

                    UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged

                };



            Binding bindingToStr2=new Binding("MethodParameters[1]")

                {

                    Source = odp,

                    BindsDirectlyToSource = true,

                    UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged

                };



            Binding bindingToResult=new Binding("."){Source = odp};



            // Binding UI 

            this.TextBoxStr1.SetBinding(TextBox.TextProperty, bindingToStr1);

            this.TextBoxStr2.SetBinding(TextBox.TextProperty, bindingToStr2);

            this.TextBoxResult.SetBinding(TextBox.TextProperty, bindingToResult);

        }

9. 데이터에 대한 전환과 검사 Binding의 역할은 Source와 Target 사이에 다리를 놓는 것이다. 이 다리에 관문을 설치하여 데이터의 유효성을 검사할 수 있다. Binding 양쪽에서 서로 다른 데이터 유형을 요구할 때 우리는 데이터에 전환기를 설정할 수 있다.
Binding 데이터 유효성 검사를 위한 관문
 
 
 
 
 
 
 
 
 
 
 

좋은 웹페이지 즐겨찾기