2016-07-07 44 views
3

我无法使用用户控件绑定到我的应用中。这是一个带有模板10的UWP应用程序。使用模板的UWP用户控件中的数据绑定10

我在主页中使用与用户控件中相同的绑定,但用户控件中的字段不会对更改作出反应。我已阅读了几篇文章,告诉我如何设置用户控件的数据内容,但我无法让它们中的任何一个工作。

我的代码如下:

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和搜索“绑定表达”看看是否有任何错误,并张贴他们请 –

+0

Text =“{x:绑定View.TextToShow,模式= OneWay}”@llnspectable – lindexi

回答

3

乍一看问题你的UserCo ntrol和您的MainPage使用两个不同的ViewModel实例。当您创建静态资源时

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

您正在创建MainPageViewModel的实例。这意味着当您从MainPageViewModel的MainPage实例中设置值时,它不会传播到您的UserControl创建的第二个MainPageViewModel实例。

不用担心,我们可以解决这个问题。

用户控件的DataContext应自动设置为其父级的DataContext。

让我们承担您使用用户控件在MainPage.xaml中

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

<MyUserControls:MyUserControl /> 

在这种情况下,是的MyUserControl使用MainPageViewModel因为它的DataContext片刻。但是,这可能不起作用,这不是一个完整的解决方案。

你需要做的是去你的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的
  • 我们创造了我们的用户控件的依赖属性,我们可以绑定到
  • 我们约束用户控件的XAML我们依赖属性
  • 我们我们认为模型的文本属性绑定到我们的新用户控件的依赖属性。
+0

感谢这么多工作就像一个魅力! – BeebFreak

+0

@BeebFreak没问题。我很乐意提供帮助 –