【问题标题】:Databind text to a string property将文本数据绑定到字符串属性
【发布时间】:2013-08-09 06:58:37
【问题描述】:

我是 Silverlight 和数据绑定概念的新手,但我仍然无法解决我的问题。经过几天的研究,我还没有找到解决方案。

这是我的问题:

我正确地将String 属性绑定到我的TextBlock 的文本,如下所示:

MainPage.xaml

<Grid  Background="Blue"  DataContext="{StaticResource WP8Displayable}">
        <TextBlock x:Name="tbCanvasTitle" TextWrapping="Wrap" Text="{Binding titleDisplayable}" FontWeight="Bold" HorizontalAlignment="Center"/>          
</Grid>

WP8Displayable.cs

public class WP8Displayable : IDisplayable, INotifyPropertyChanged
{

    public String title { get; set; }


    #region INotifyPropertyChanged Members


    public string titleDisplayable
    {
        get
        {
            return title;
        }
        set
        {
            if (title != value)
            {
                title = value;
                NotifyPropertyChanged("titleDisplayable");
            }
        }
    }



    public event PropertyChangedEventHandler PropertyChanged;

    // Used to notify the page that a data context property changed
    private void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion

    public void setTitle(String s)
    {
        this.title = s;

        NotifyPropertyChanged("titleDisplayable");
    }
}

我的MainPage.xaml.cs 中有一个线程可以实例化WP8Displayable 类的一个或多个实例。当其中一个实例调用setTitle(String s) 时,我的TextBlock 中的文本没有更新,似乎我的DataContext 设置不正确。

编辑:

我的线程在MainPage_Loaded(object sender, RoutedEventArgs e) 方法中的MainPage.xaml.cs 中启动,并执行以下操作:

  var instanceWP8Displayable = new WP8Displayable();
  //tbCanvasTitle.DataContext = instanceWP8Displayable;   HERE IS WHAT I WOULD LIKE TO DO ON XAML
  instanceWP8Displayable.setTitle("my Title");

编辑 2:App.xaml

<Application
x:Class="AMS.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:windows="clr-namespace:System.Windows;assembly=System.Windows"
xmlns:ioC="clr-namespace:AMS.Controller">

<!--Application Resources-->
<Application.Resources>

    <windows:ResourceDictionary>
        <local:LocalizedStrings xmlns:local="clr-namespace:AMS" x:Key="LocalizedStrings"/>
        <ioC:Locator x:Key="Locator" x:Name="Locator" />
    </windows:ResourceDictionary>
</Application.Resources>

MainPage.xaml

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid  Background="Blue"  DataContext="{Binding Source={StaticResource Locator}, Path=WP8Displayable}">
        <TextBlock x:Name="tbCanvasTitle" TextWrapping="Wrap" Text="{Binding titleDisplayable}" FontWeight="Bold" HorizontalAlignment="Center"/>          
    </Grid>
    <Grid.DataContext>
        <local:WP8Displayable />
    </Grid.DataContext>
    </Grid>

在这种情况下如何动态设置 DataContext是否可以将多个实例链接到同一个对象?

如果有人作为线索或觉得我的问题不够清楚,请随时告诉我。

谢谢。

【问题讨论】:

  • 在后面的代码中设置datacontext时标题会更新对吗?
  • 是的,它有效。我试了一下以确保我的绑定没问题。但我不知道何时会创建多少个 WP8Displayable 实例。

标签: c# silverlight data-binding windows-phone-8


【解决方案1】:

我建议您查看MVVMLight,这将帮助您消除必须编写的大量样板代码,例如INotifyPropertyChanged。此外,它还为您提供了最常用于您尝试执行的任务的 IoC 容器(控制反转)。您可以自己实现一个简单版本(见下文)。

您可以在 XAML 中设置 DataContext,但您需要一个提供对象的类,因此例如您可以编写这样的类(我假设您将它直接添加到项目中,而不是在子文件夹中):

public class Locator
{
    public WP8Displayable WP8Displayable
    {
        get { return new WP8Displayable(); }
    }
}

接下来,您必须在 App.xaml 中注册 Locator 类,以便您可以在视图中引用它:

<Application
    ...
    xmlns:windows="clr-namespace:System.Windows;assembly=System.Windows"
    xmlns:ioC="clr-namespace:YOURAPPNAME">

 <!--Application Resources-->

 <Application.Resources>      
     <windows:ResourceDictionary>
         <local:LocalizedStrings xmlns:local="clr-namespace:AMS" x:Key="LocalizedStrings"/>
         <ioC:Locator x:Key="Locator" x:Name="Locator" />
     </windows:ResourceDictionary>
 </Application.Resources>



        ...

</Application>

现在我们可以在 XAML 中设置 DataContext:

<Grid  Background="Blue"  DataContext="{Binding Source={StaticResource Locator}, Path=WP8Displayable}">
        <TextBlock x:Name="tbCanvasTitle" TextWrapping="Wrap" Text="{Binding titleDisplayable}" FontWeight="Bold" HorizontalAlignment="Center"/>          
</Grid>

HTH

【讨论】:

  • 很遗憾,Silverlight 项目不支持 ResourceDictionary。因此,如果我理解得很好,我必须在 Class 中创建我的 WP8Displayable 对象,该对象可用于在 XAML 中设置 DataContext 对吗?
  • @Yann 对不起,我的错误删除了太多行,有了额外的命名空间,您可以在 WP8 项目中使用ResourceDictionary
  • @Yann 是的,如果您不通过后面的代码使用它。您当然可以调整该方法,使其始终返回该类的相同实例。所以是的,您可以将WP8Displayable 实例设置为多个视图的DataContext
  • 感谢您,我发现了“控制反转”模式。我实际上是在尝试理解它以便正确应用它。
  • @Yann 是的,这是朝着那个方向发展的。抱歉,Locator 方法应该是一个属性,否则它找不到它。进一步确保将字符串 YOURAPPNAME 替换为您的实际应用名称。
【解决方案2】:

您声明属性的方式是错误的。 请声明如下属性;

#region INotifyPropertyChanged Members

public string _titleDisplayable;
public string titleDisplayable
{
    get
    {
        return _titleDisplayable;
    }
    set
    {
        if (_titleDisplayable != value)
        {
            _titleDisplayable = value;
            NotifyPropertyChanged("titleDisplayable");
        }
    }
}

在类方法中请写下代码:

public void setTitle(string s)
{
    this.titleDisplayable = s;

}

请按照上述代码更改您的代码。

谢谢, 希特什。

【讨论】:

  • 感谢您的回答,但我的投标工作正常。如果我创建一个 WP8Displayable 实例并在此行中设置 DataContexttbCanvasTitle.DataContext = instanceWP8Displayable;(我的代码中的注释)它工作正常,但问题是我不能使用该行。
猜你喜欢
  • 1970-01-01
  • 2012-04-20
  • 2012-01-29
  • 2019-08-07
  • 2010-10-16
  • 1970-01-01
  • 1970-01-01
  • 2012-07-24
  • 1970-01-01
相关资源
最近更新 更多