簡體   English   中英

使用模板10在UWP用戶控件中進行數據綁定

[英]Data Binding in UWP User Controls using Template 10

我無法使用用戶控件在我的應用程序中工作。 它是一個帶有模板10的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>

乍一看,問題是您的UserControl和您的MainPage正在使用兩個不同的ViewModel實例。 創建靜態資源時

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

您正在創建MainPageViewModel的實例。 這意味着當您從MainPageViewModel的MainPage實例設置值時,它不會傳播到您的UserControl創建的第二個MainPageViewModel實例。

不用擔心,我們可以解決這個問題。

應將用戶控件的DataContext自動設置為其父級的DataContext。

因此,讓我們暫時假設您在MainPage.xaml中使用UserControl

 <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
  • 我們在UserControl中創建了一個可以綁定的依賴屬性
  • 我們將UserControl的XAML綁定到依賴屬性
  • 我們將視圖模型的text屬性綁定到新的用戶控件依賴項屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM