【问题标题】:UWP "compound" binding (binding Data.Name instead of Name)UWP“复合”绑定(绑定 Data.Name 而不是 Name)
【发布时间】:2019-01-03 22:43:44
【问题描述】:

我有一个带有文本块和按钮的简单页面。我想在按下按钮时更改文本。但是使用 Page 的 Data.Name 属性中的文本。

我知道我可以有这个更简单的(只有 Name 而不是 Data.Name),但我需要 Data.Name,不要问为什么。

为此,我有一个 DataType 类,它具有该类的 Name 属性和名为 Data 的对象。我想在此页面中包含数据,并将文本绑定到 Data.Name 属性。

当我点击按钮时,什么也没有发生,问题是我怎样才能做到这一点?

XAML

<Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition Height="auto" />
        </Grid.RowDefinitions>

        <TextBlock Grid.Row="0" Text="{Binding Data.Name, Mode=OneWay}"/>
        <Button Grid.Row="1" Content="Change" Click="Button_Click"/>
    </Grid>
</Page>

数据类型

public ref class DataType: public INotifyPropertyChanged {
public:
    property String^ Name
    {
        String^ get() {
            return m_Name;
        }
        void set(String^ value) {
            m_Name = value;
            OnPropertyChanged("Name");
        }
    }

    virtual event PropertyChangedEventHandler^ PropertyChanged;

private:
    void OnPropertyChanged(Platform::String^ propertyName)
    {
        PropertyChanged(this, ref new PropertyChangedEventArgs(propertyName));
    }
    String^ m_Name;
};

MainPage

public ref class MainPage sealed: public INotifyPropertyChanged
{
public:
    MainPage();

    property DataType^ Data {
        DataType^ get() {
            return m_Data;
        }
        void set(DataType^ value) {
            m_Data = value;
            OnPropertyChanged("Data");
        }
    }

    virtual event PropertyChangedEventHandler^ PropertyChanged;


private:
    void OnPropertyChanged(Platform::String^ propertyName)
    {
        PropertyChanged(this, ref new PropertyChangedEventArgs(propertyName));
    }
    void Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
    {
        Data->Name = rand() & 1 ? "Test1" : "Test2";
        OnPropertyChanged("Data");
    }


    DataType^ m_Data;
};

【问题讨论】:

  • 你试过x:Bind 吗?
  • 您需要将页面的DataContext设置为自身。您可以在页面声明中执行此操作,例如
    @Muzib,我尝试了 x:Bind 并找出了错误。将其发布在我的答案中。

标签: xaml binding uwp


【解决方案1】:

在 UWP 中,有x:BindBinding 标记扩展,它们在使用时会有所不同。您可以从以上两个链接的文档中了解详细信息。

现在我们将讨论导致您上述问题的原因。

在您的 xaml 中,您使用 Binding 标记扩展来绑定属性路径,因为 Binding 使用 DataContext 作为默认源。简单来说,当你使用Binding属性路径时,你绑定的是DataContext.Property路径,你只需要使用Bind源对象的属性而不需要在xaml中指定Source数据对象。作为Traversing an object graph的介绍:

"{Binding Path=Customer.Address.StreetAddress1}"

这是评估此路径的方式:

  1. 在数据上下文对象(或由相同绑定指定的源)中搜索名为“客户”的属性。

  2. 在作为“客户”属性值的对象中搜索名为“地址”的属性。

  3. 在作为“地址”属性值的对象中搜索名为“StreetAddress1”的属性。

详情请见Property-path syntax

所以您的代码只需绑定Name 属性并设置DataContext 即可工作。 (注意:你的 MainPage 类不需要实现INotifyPropertyChanged 接口。)

<TextBlock Grid.Row="0" Text="{Binding Name, Mode=OneWay}"/

this->DataContext = Data;

另请注意:如果您使用 Visual C++ 组件扩展 (C++/CX),因为我们将使用 {Binding},您需要将 BindableAttribute 属性添加到 DataType 类。

[Windows::UI::Xaml::Data::Bindable]
public ref class DataType sealed : public INotifyPropertyChanged {
...
}

另一方面,您可以使用x:Bind 代替Binding,因为x:Bind 不使用DataContext 作为默认源,而是使用页面或用户控制本身。因此,它将在您的页面或用户控件的代码隐藏中查找属性、字段和方法。要将您的视图模型公开给 {x:Bind},您通常需要为页面或用户控件的代码添加新字段或属性。例如:在页面中,Text="{x:Bind Employee.FirstName}" 将在页面上查找 Employee member,然后查找 FirstNameEmployee 返回的对象上的 /strong> 成员。

【讨论】:

    【解决方案2】:

    问题是 DataType 属性在 XAML 中不可见,因为“pch.h”中不包含“DataType.h”

    一旦我将它包含在预编译的标头中,一切正常。

    顺便说一句,Binding 似乎没有从 XAML 或其他任何东西中检查类型可见性,但 x:Bind 会。使用 x:Bind,编译器会抱怨未知的 Data.Name,这让我能够找出问题所在。

    【讨论】:

      猜你喜欢
      • 2019-09-29
      • 2020-02-01
      • 2011-02-24
      • 2017-07-18
      • 2018-08-31
      • 2018-03-15
      • 2022-01-09
      • 2018-04-13
      • 2019-04-13
      相关资源
      最近更新 更多