将C#中的绑定翻译为XAML

3

我希望您能够在XAML中进行绑定,但是遇到了问题。

C#中的绑定是有效的:

public partial class myControl : UserControl
{
    // get singleton instance
    InfoPool Info = InfoPool.Info;

    public myControl()
    {
        InitializeComponent();

        // Test Binding
        Binding bind = new Binding();
        bind.Source = this.Info;
        bind.Path = new PropertyPath("Time");
        txtInfoTime.SetBinding(TextBlock.TextProperty, bind);
    }
}

XAML中的绑定不是:

<TextBlock x:Name="txtInfoTime" Text="{Binding Path=Time, Source=Info}" />

路径和源相同,那么我的错误在哪里?
谢谢 Rob。
5个回答

5

您无法使用完全相同的属性将其转换为XAML,因为没有直接引用this.Info的方法。但是,您可以通过设置RelativeSource来达到相同的效果:

<TextBlock x:Name="txtInfoTime" Text="{Binding Path=Info.Time, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:myControl}}}" />

谢谢你的回答,但我会使用另一种解决方案。 - Robert Vernunft

2

您需要设置数据上下文。

您可以添加以下代码:

DataContext = Info

之后

InitializeComponent();

将XAML更改为:

<TextBlock x:Name="txtInfoTime" Text="{Binding Time}" />

2
如果他这样做,UserControl 中的所有内容都将具有 Info 作为 DataContext,并且将无法绑定到其他内容... - Thomas Levesque
所以我认为这种绑定更容易,因为在这个控件中不需要绑定到其他控件。 - Robert Vernunft

1

由于InfoPool是一个单例实例,我建议采用以下方式:

<TextBlock x:Name="txtInfoTime" Text="{Binding Path=Time, Source={x:Static ns:InfoPool.Info}}"/>

ns是XAML中InfoPool命名空间的别名。不需要这样弄乱您的DataContext。


1
根据您的回答,我按照以下描述解决了问题。我发布它,因为我认为其他WPF初学者可能会发现它有用。
我有一个单例类(InfoPool.cs),它实现了INotifyChangedProperty。它用于提供应用程序范围内可绑定属性。这个类被App.xaml中的ObjectDataProvider使用。所以很容易绑定到属性。
InfoPool.cs(Singleton代码来自http://csharpindepth.com/Articles/General/Singleton.aspx第5版。我将Instance属性更改为GetInstance()方法,因为OPD需要一个方法)。
public sealed class InfoPool : INotifyPropertyChanged
{
    InfoPool()
    {
    }

    public static InfoPool GetInstance()
    {
        return Nested.instance;
    }

    class Nested
    {
        static Nested()
        {
        }

        internal static readonly InfoPool instance = new InfoPool();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, e);
        }
    }

    private String strProp = "default String";
    private Double dblProp = 1.23456;

    public String StrProp
    {
        get { return strProp; }
        set 
        { 
            strProp = value;
            OnPropertyChanged(new PropertyChangedEventArgs("StrProp"));
        }
    }

    public Double DblProp
    {
        get { return dblProp; }
        set 
        { 
            dblProp = value;
            OnPropertyChanged(new PropertyChangedEventArgs("DblProp"));
        }
    }

App.xaml 中的 ObjectDataProvider

<Application.Resources>
    <ResourceDictionary>
        <ObjectDataProvider x:Key="OPDInfo" ObjectType="{x:Type local:InfoPool}" MethodName="GetInstance" d:IsDataSource="True"/>
    </ResourceDictionary>
</Application.Resources>

这里有两种绑定到OPD的方式

<StackPanel>
    <TextBlock x:Name="tbprop1" Text="{Binding Path=StrProp, Source={StaticResource OPDInfo}}" />
    <TextBlock x:Name="tbprop2" Text="{Binding DblProp}" ToolTip="{Binding StrProp}" DataContext="{StaticResource OPDInfo}" />
</StackPanel>

就是这样。请评论,因为我对此很新奇;-)


1
如果您将单例实例访问器保留为属性,则不需要ObjectDataProvider。您可以直接使用静态实例。
<StackPanel>
<TextBlock x:Name="tbprop1" 
    Text="{Binding Path=StrProp, Source={x:Static local:InfoPool.Instance}}" /> 
</StackPanel>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接