집 >백엔드 개발 >C#.Net 튜토리얼 >WPF의 바인딩 표현식에 대한 간략한 토론
컨트롤을 정의하든 사용자 컨트롤을 정의하든 함수 바인딩을 사용하게 됩니다. 작성된 이름: 요소 바인딩. 이는 바인딩된 요소가 데이터 동기화를 달성할 수 있음을 의미합니다. 저자의 의견에 따르면 이 기능을 WPF에 도입한 것은 정말 완벽했습니다. 프로그래밍이 더 구체적입니다. 특히 MVVM 모델과 결합하면 완벽합니다. 저자는 학자가 아니다. 포괄적으로 말하는 것은 비현실적입니다. 저자의 경험을 바탕으로 Binding에 대해 이야기해 보겠습니다.
이를 사용하는 가장 일반적인 방법은 대상 요소가 컨트롤의 DataContext 개체라는 것입니다. 다음과 같습니다.
<TextBlock Grid.Column="0" Text="{Binding DishName}" Style="{StaticResource TakingDishDishNameTextStyle}" />
DataContext 이 속성은 FrameworkElement 클래스에 있습니다. 즉, 대부분의 컨트롤에는 자체 DataContext가 있습니다. 그런 다음 일반적으로 가장 바깥쪽 레이어에만 DataContext 속성을 설정합니다. DataContext 바인딩을 더 명확하게 이해하기 위해. 저자는 간단한 예를 들었다. 작성자는 가장 바깥쪽 Window에 대한 DataContext 값을 설정합니다. 동시에 내부 Grid에 대한 DataContext 값도 설정됩니다. 그러나 그것들은 동일한 객체 유형이 아니며 단지 동일한 속성을 가지고 있을 뿐입니다.
<Window x:Class="Wpf.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:aomi="http://aomiwpf.com/ModernUI"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local ="clr-namespace:Wpf"Title="MainWindow" Height="350" Width="525"><Window.DataContext><local:WindDataContext /></Window.DataContext><Grid><Grid.DataContext><local:GridDataContext /></Grid.DataContext><TextBlock Text="{Binding TestName}"></TextBlock></Grid></Window>
의 실행 결과는 다음과 같습니다.
실험을 통해 표준 바인딩 방식의 대상 요소가 DataContext임을 증명할 수 있습니다. 현재 바인딩된 요소에 가장 가까운 DataContext를 찾습니다. 가설을 세워 보겠습니다. GridDataContext 클래스의 TestName 속성이 TestName1로 대체되면 어떻게 될까요?
1 public class GridDataContext : NotifyPropertyChanged 2 { 3 private string _testName1 ="GridDataContext"; 4 5 public string TestName1 6 { 7 set 8 { 9 10 if (this._testName1 != value)11 {12 this._testName1 = value;13 OnPropertyChanged("TestName1");14 }15 }16 get { return this._testName1; }17 }18 }
의 실행 결과는 다음과 같습니다.
죄송합니다! 작성자는 Window DataContext의 TestName 속성으로 이동할 것이라고 생각했습니다. 분명히 그는 그렇지 않습니다. 또한 가장 가까운 DataContext에서만 검색할 것이라고 설명합니다. 일일이 찾으러 바로 가지 않겠습니다.
위에 {Binding}만 작성하면 현재 DataContext를 바인딩한다는 점에 주목할 필요가 있습니다. 그 사람의 속성보다는
개발 과정에서 요소가 다른 요소의 속성에 바인딩될 수 있기를 바라는 경우가 많습니다. 다른 요소의 속성이 변경되는 한 해당 요소도 함께 변경되도록 알림을 받습니다. 이때 다음과 같은 방법을 사용해야 합니다.
{Binding ElementName=SomeThingName, Path=Text}
ElementName: 요소의 이름을 나타냅니다.
Path: 요소 개체의 속성을 나타냅니다.
사실 우리는 한 가지 질문을 생각해 볼 수 있습니다. 바인딩은 한 당사자에게만 영향을 미치나요? 바인딩에 사용되는 모드입니다. 다음과 같습니다
{Binding ElementName=SomeThindName, Path=Text,Mode=TwoWay}
TwoWay: 소스 속성 또는 대상 속성에 대한 변경 사항이 자동으로 다른 속성을 업데이트하도록 합니다.
OneWay: 바인딩 소스(source)가 변경되면 바인딩 대상(target) 속성을 업데이트합니다.
OneTime: 애플리케이션이 시작되거나 데이터 컨텍스트가 변경되면 바인딩 대상을 업데이트합니다.
OneWayToSource: 대상 속성이 변경되면 소스 속성을 업데이트합니다.
위의 사용법은 비교적 일반적입니다. 또한 비교적 간단합니다. 오픈 소스 프로젝트의 바인딩 표현식을 살펴보겠습니다. 다음과 같습니다
<Button Command="{Binding Source={x:Static SystemCommands.MinimizeWindowCommand}}" ToolTip="{x:Static modernui:Resources.Minimize}" Style="{StaticResource SystemButton}"> <Button.Content> <Grid Width="13" Height="12" RenderTransform="1,0,0,1,0,1"> <Path Data="M0,6 L8,6 Z" Width="8" Height="7" VerticalAlignment="Center" HorizontalAlignment="Center" Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="2" /> </Grid> </Button.Content></Button>
확실히 보이실지 모르겠네요. 위의 내용은 상위 노드 Button의 Foreground와 현재 Path의 Stroke가 함께 바인딩되어 있음을 의미합니다. 기본 키는 AncestorType입니다. 아버지 유형을 지정하는 데 사용됩니다. 모드는 RelativeSourceMode 유형입니다. 그에게는 네 가지 가치관이 있다. 다음과 같이.
PreviousData: 데이터 목록에 사용되며 이전 데이터 항목을 의미합니다. 이것이 데이터 수집 위의 표시입니다. 컨트롤은 포함되어 있지 않습니다.
TemplateParent: 템플릿 바인딩에 사용됩니다.
Self: 요소 자체의 속성에 바인딩됩니다.
FindAncestor: 상위 요소를 찾는 데 사용됩니다.
이렇게 설명하면 RelativeSource는 상대 소스 요소를 지정하는 데 사용된다는 것을 이해할 수 있습니다. 그것이 대상 요소입니다.
사실 위 표현을 쓰는 또 다른 방법도 있습니다. 즉, 상위를 제한하는 데 사용되는 깊이(AncestorLevel)가 하나 더 있습니다. 다음과 같습니다
{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}, AncestorLevel=2}, Path=Name}
참고: 바인딩된 값을 수정하려면 변환기를 사용해야 합니다. 다음과 같습니다
{Binding ElementName=SomeThindName, Path=Text,Mode=TwoWay,Converter=XXXConverter}
사용자 정의 컨트롤을 개발할 때 표현식을 자주 사용합니다. 다음과 같습니다
Width="{TemplateBinding Width}"
위의 글은 그냥 생략한 것입니다. 전체 목록은 다음과 같습니다
Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Width}"
작가가 가장 많이 사용하는 내용은 위의 내용이라고 할 수 있습니다. 다음으로 다른 콘텐츠 포인트를 바인딩하는 방법을 살펴보겠습니다. 즉, 흔하지 않은 콘텐츠이다.
1.StringFormat 함수. string.format 함수와 동일합니다. 예를 들어보세요. 금액 앞에 "엔"을 추가하고 싶다면 사용할 수 있습니다. 다음과 같습니다
<TextBlock Text="{Binding MoneyText, StringFormat=¥{0}}" />
如果不是这样子做的话,你就不得不给“¥”一个TextBlock来显示,或是MoneyText变成string类型,然后设置值里面加上¥。但是笔者这里却是double类型的。所以用StringFormat的功能有就可以完美的决解了显示“¥”的问题。
执行结果:
2.TargetNullValue的功能,用于绑定目标是一个null值的时候,要显示的内容。如下笔者给NullName赋null。
<TextBlock Text="{Binding NullName, TargetNullValue=aomi}" />
执行结果:
3.FallbackValue的功能,用于绑定目标是发生错误的时候,要显示的内容。如下
<TextBlock Text="{Binding NullName, FallbackValue=aomi}" />
执行结果笔者就不贴了。
文章最后。在来说明一个不常用的功能——PriorityBinding。这个功能笔者不好说。只能让读者们自行体会吧。他主要用于在加载时间比较多的时候,要显示的信息。比如显示“正在加载中...”。笔者做了例子吧。
Xaml:
<Window x:Class="Wpf.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:aomi="http://aomiwpf.com/ModernUI"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local ="clr-namespace:Wpf"Title="MainWindow" Height="350" Width="525"><Window.DataContext><local:MainViewModel /></Window.DataContext><Grid><TextBlock><TextBlock.Text><PriorityBinding><Binding Path="UserName" IsAsync="True"></Binding><Binding Path="LoadingName"></Binding></PriorityBinding></TextBlock.Text></TextBlock></Grid></Window>
ViewModel:
public class MainViewModel : NotifyPropertyChanged {private string _userName ="Haya";private string _loadingName = "正在加载中...";public string UserName {set{if (this._userName != value) {this._userName = value; OnPropertyChanged("UserName"); } }get { Thread.Sleep(7000);return this._userName; } }public string LoadingName {set{if (this._loadingName != value) {this._loadingName = value; OnPropertyChanged("LoadingName"); } }get { return this._loadingName; } } }
执行结果:
七秒后:
本章的内容比较简单。笔者只是讲述了常用的一些知识点。但是必不是说就这些了。例如Binding还关系到Xml的绑定和集合的绑定功能。读者们可以自行去找一下资料。
위 내용은 WPF의 바인딩 표현식에 대한 간략한 토론의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!