将绑定从C#转换为XAML

时间:2010-08-18 13:37:54

标签: c# wpf xaml binding

我无法在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}" />

路径和来源是一样的,所以我的错误在哪里?

Thx Rob

5 个答案:

答案 0 :(得分:5)

您无法将其转换为具有完全相同属性的XAML,因为无法直接引用this.Info。但是,您可以通过设置RelativeSource

来获得相同的结果
<TextBlock x:Name="txtInfoTime" Text="{Binding Path=Info.Time, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:myControl}}}" />

答案 1 :(得分:2)

您需要设置DataContext。

你可以添加:

DataContext = Info

之后

InitializeComponent();

将XAML更改为:

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

答案 2 :(得分:1)

由于InfoPool是一个单例实例,我建议如下:

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

其中ns是定义InfoPool的命名空间的xaml-alias。 不需要以这种方式弄乱你的DataContext。

答案 3 :(得分:1)

根据您的回答,我解决了如下所述的问题。我发布它,因为我猜WPF中的其他初学者会发现它很有用。

我有单独的类(InfoPool.cs),它实现了INotifyChangedProperty。它用于提供appwide可绑定属性。此类由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>

就是这样。请评论,因为我是新手; - )

答案 4 :(得分:1)

如果将单例实例访问器保留为属性,则不需要ObjectDataProvider。您可以直接使用静态实例。

<StackPanel>
<TextBlock x:Name="tbprop1" 
    Text="{Binding Path=StrProp, Source={x:Static local:InfoPool.Instance}}" /> 
</StackPanel>