2016-07-07 3 views
3

사용자 정의 컨트롤을 사용하여 내 앱에서 바인딩이 작동하지 않습니다. 템플리트가있는 UWP 응용 프로그램입니다.템플릿을 사용하는 UWP 사용자 컨트롤의 데이터 바인딩

사용자 정의 컨트롤에서와 같이 주 페이지에서 동일한 바인딩을 사용하지만 사용자 정의 컨트롤의 필드가 변경에 반응하지 않습니다. 내 사용자 컨트롤의 datacontent를 설정하는 방법을 알려주는 여러 기사를 읽었으나 그 중 일부는 작동하지 않습니다.

에서 MainPage.xaml

Page x:Class="UserControlTest.Views.MainPage" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:Core="using:Microsoft.Xaml.Interactions.Core" 
     xmlns:Interactivity="using:Microsoft.Xaml.Interactivity" 
     xmlns:controls="using:Template10.Controls" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:local="using:UserControlTest.Views" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:vm="using:UserControlTest.ViewModels" mc:Ignorable="d"> 

    <Page.DataContext> 
     <vm:MainPageViewModel x:Name="ViewModel" /> 
    </Page.DataContext> 

    <RelativePanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 

     <controls:PageHeader x:Name="pageHeader" Content="Main Page" 
          RelativePanel.AlignLeftWithPanel="True" 
          RelativePanel.AlignRightWithPanel="True" 
          RelativePanel.AlignTopWithPanel="True" /> 

     <TextBlock x:Name="mainTextBlock" Margin="16,16,16,16" 
        RelativePanel.AlignLeftWithPanel="True" 
        RelativePanel.Below="pageHeader" 
        Text="{Binding TextToShow}" /> 

     <local:ShowText Margin="16,16,16,16" 
      RelativePanel.Below="pageHeader" 
      RelativePanel.AlignRightWithPanel="True"/> 

     <Button Content="Change Text" Margin="16,16,16,16" 
       Command="{x:Bind ViewModel.ChangeText }" 
       RelativePanel.AlignLeftWithPanel="True" 
       RelativePanel.Below="mainTextBlock"/> 
    </RelativePanel> 

</Page> 

MainPageViewModel.cs

using System.Collections.Generic; 
    using System; 
    using System.Linq; 
    using System.Threading.Tasks; 
    using Windows.Security.Cryptography.Core; 
    using Template10.Mvvm; 
    using Template10.Services.NavigationService; 
    using Windows.UI.Xaml.Navigation; 

    namespace UserControlTest.ViewModels 
    { 
    public class MainPageViewModel : ViewModelBase 
    { 
     private string _textToShow = "Initial text"; 

     public string TextToShow 
     { 
      get { return _textToShow; } 
      set { Set(ref _textToShow, value); } 
     } 

     DelegateCommand _changeText; 

     public DelegateCommand ChangeText 
      => _changeText ?? (_changeText = new DelegateCommand(ExecuteChangeTest, CanChangeText)); 

     private void ExecuteChangeTest() 
     { 
      TextToShow = "Changed text"; 
     } 

     private bool CanChangeText() 
     { 
      return true; 
     } 
    } 
} 

을 문제가 언뜻 ShowText.xaml

<UserControl 
    x:Class="UserControlTest.Views.ShowText" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:UserControlTest.Views" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:vm="using:UserControlTest.ViewModels" mc:Ignorable="d"> 

    <UserControl.DataContext> 
     <vm:MainPageViewModel x:Name="ViewModel" /> 
    </UserControl.DataContext> 

    <Grid> 
     <TextBlock x:Name="UserControlTextBlock" 
        Text="{Binding TextToShow}" /> 
    </Grid> 
</UserControl> 
+0

사용자 컨트롤이 'INotifyPropertyChanged' 인터페이스를 구현합니까? '{x : Bind ...} '를 지원하는 Windows 10 UWP에서 구식'{Binding ...}'을 사용하는 것은 다소 이례적입니다. – IInspectable

+0

출력 창이 어떻게됩니까? CTL + F와 "Binding Expression"을 검색하여 오류가 있는지 확인하고 게시 할 수 있습니까? –

+0

Text = "{x : Bind View.TextToShow, Mode = OneWay}"@llnspectable – lindexi

답변

3

다음과 같이

내 코드입니다 당신의 UserCo ntrol과 MainPage는 두 개의 ViewModel 인스턴스를 사용합니다. 고정 리소스를 만들 때

 <vm:MainPageViewModel x:Name="ViewModel" /> 

MainPageViewModel의 인스턴스를 만듭니다. 즉, MainPageViewModel의 MainPage 인스턴스에서 값을 설정하면 UserControl이 만든 MainPageViewModel의 두 번째 인스턴스로 전파되지 않습니다.

걱정할 필요는 없지만 해결할 수 있습니다.

사용자 정의 컨트롤의 DataContext는 부모의 DataContext에 자동으로 설정되어야합니다.

그래서 당신이

<Page.DataContext> 
    <vm:MainPageViewModel x:Name="ViewModel" /> 
</Page.DataContext> 

<MyUserControls:MyUserControl /> 
이 경우

그것의 DataContext의로,을 MyUserControl가 MainPageViewModel을 사용하여에서 MainPage.xaml에서 UserControl을을 사용하여 잠시 가정 해 보자. 그러나 이것은 아마도 작동하지 않을 것입니다. 그것은 완벽한 해결책이 아닙니다.

당신이해야 할 일은 UserControl의 Xaml.CS로 가서 바인딩 할 수있는 종속성 속성을 만드는 것입니다.

public class MyUserControl : Control{ 

    public string MyControlsText 
    { 
     get { return (string)GetValue(MyControlsTextProperty); } 
     set { SetValue(MyControlsTextProperty, value); } 
    } 

    public static readonly DependencyProperty MyControlsTextProperty = 
      DependencyProperty.Register("MyControlsText", typeof(string), 
       typeof(MyUserControl), new PropertyMetadata(String.Empty)); 

    } 

이제 UserControl의 Xaml에서 종속성 속성이 바인딩되었습니다.

<Grid> 
    <TextBlock x:Name="UserControlTextBlock" 
       Text="{Binding MyControlsText}" /> 
</Grid> 

그리고 마지막으로 우리의에서 MainPage.xaml에서 우리는 마무리 할 수있는 그래서 여기에 위의 코드와

<MyUserControls:MyUserControl MyControlsText="{Binding TextToShow}" /> 

우리가 달성하는 것입니다 바인딩 :

  • DataContext를이 설정됩니다 MainPage.xaml과 MainPage의 모든 하위 항목들.XAML 점유율이 DataContext를 우리는
  • 우리는 우리의 새로운 사용자에게 우리의 뷰 모델의 텍스트 속성을 바인딩 우리는 우리의 종속성 속성에 우리의 UserControl의 XAML을 결합 우리는
  • 에 결합 할 수있는 우리의 UserControl에서 종속성 속성을 만들어
  • 의존성을 제어 재산.
+0

감사합니다. – BeebFreak

+0

@BeebFreak 문제 없습니다. 기꺼이 도와 드리겠습니다. –