c# - 使用模板 10 在 UWP 用户控件中进行数据绑定(bind)

标签 c# xaml data-binding uwp template10

我无法通过用户控件在我的应用程序中绑定(bind)工作。这是一个带有模板 10 的 UWP 应用程序。

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

我的代码如下:

主页.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;
        }
    }
}

显示文本.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 并创建一个您可以绑定(bind)到的依赖属性。

 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 中我们可以绑定(bind)到它。

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

最后在我们的 MainPage.Xaml 中我们可以完成绑定(bind)

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

所以上面的代码就是我们正在完成的:

  • DataContext 在 MainPage.xaml 中设置,MainPage.xaml 的所有子级共享此 DataContext
  • 我们在 UserControl 中创建了一个可以绑定(bind)的依赖属性
  • 我们将 UserControl 的 XAML 绑定(bind)到我们的依赖属性
  • 我们将 View 模型的文本属性绑定(bind)到我们新的用户控件依赖属性。

关于c# - 使用模板 10 在 UWP 用户控件中进行数据绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38247631/

相关文章:

c# - 删除组合框中最后输入的字符

xaml - listview 绑定(bind) selectedItems

c# - user.identity.name (c#) 从哪里获得它的值(value)?

c# - MySqlConnection.StateChange 永远不会获取

c# - 如何在 wpf 中的文本绑定(bind)前面添加项目符号?

c# - 新的 .Net MAUI App 项目抛出 'The name ' InitializeComponent' 在当前上下文中不存在' 构建错误

c# - Silverlight:奇怪的数据绑定(bind)问题

android - 如何在 fragment 中使用数据绑定(bind)

database - 如何使用ADT表重试Delphi TAdsConnection

c# - 解析 XML 的高效方法