在代码隐藏中定义的绑定对象

xan*_*ndy 81 .net c# wpf binding

我有一些在后面的代码中实例化的对象,例如,XAML被称为window.xaml并且在window.xaml.cs中

protected Dictionary<string, myClass> myDictionary;
Run Code Online (Sandbox Code Playgroud)

如何仅使用XAML标记将此对象绑定到列表视图?

更新:

(这正是我在测试代码中所拥有的):

<Window x:Class="QuizBee.Host.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="{Binding windowname}" Height="300" Width="300"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
    </Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)

并在代码隐藏

public partial class Window1 : Window
{
    public const string windowname = "ABCDEFG";

    public Window1()
    {
        InitializeComponent();
    }
}
Run Code Online (Sandbox Code Playgroud)

假设标题应该变成"ABCDEFG"吧?但它最终没有显示任何东西.

Saa*_*an. 118

有一个更容易的方法来做到这一点.您可以为Window或UserControl指定名称,然后通过ElementName绑定.

Window1.xaml

<Window x:Class="QuizBee.Host.Window1"
        x:Name="Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <ListView ItemsSource="{Binding ElementName=Window1, Path=myDictionary}" />
</Window>
Run Code Online (Sandbox Code Playgroud)

Window1.xaml.cs

public partial class Window1:Window
{
    // the property must be public, and it must have a getter & setter
    public Dictionary<string, myClass> myDictionary { get; set; }

    public Window1()
    {
        // define the dictionary items in the constructor
        // do the defining BEFORE the InitializeComponent();

        myDictionary = new Dictionary<string, myClass>()
        {
            {"item 1", new myClass(1)},
            {"item 2", new myClass(2)},
            {"item 3", new myClass(3)},
            {"item 4", new myClass(4)},
            {"item 5", new myClass(5)},
        }; 

        InitializeComponent();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • +1用于设置绑定属性BEFORE InitializeComponent() (25认同)
  • 我不得不改变x:Name(编译器错误CS0542).然后需要相应地更改ElementName. (3认同)

Guy*_*uck 101

您可以为控件,表单等设置DataContext,如下所示:

DataContext="{Binding RelativeSource={RelativeSource Self}}"
Run Code Online (Sandbox Code Playgroud)

澄清:

设置为上述值的数据上下文应该在"拥有"后面的代码的任何元素上完成 - 因此对于Window,您应该在Window声明中设置它.

我有你的例子使用这段代码:

<Window x:Class="MyClass"
  Title="{Binding windowname}"
  DataContext="{Binding RelativeSource={RelativeSource Self}}"
  Height="470" Width="626">
Run Code Online (Sandbox Code Playgroud)

然后,在此级别设置的DataContext将由窗口中的任何元素继承(除非您为子元素显式更改它),因此在为Window设置DataContext之后,您应该能够直接绑定到任何控件的CodeBehind 属性在窗户上.

  • 哦,现在好了,我将windowname改为属性而不是纯公共变量,它现在可以显示!谢谢! (8认同)
  • 我无法想象为什么这不是默认设置。 (2认同)

Cat*_*top 23

虽然Guy的答案是正确的(并且可能适合10个案例中的9个),但值得注意的是,如果您尝试从已经将其DataContext设置在堆栈中的控件上执行此操作,则在设置DataContext时将重置此项回到自己:

DataContext="{Binding RelativeSource={RelativeSource Self}}"
Run Code Online (Sandbox Code Playgroud)

这当然会破坏您现有的绑定.

如果是这种情况,则应在要尝试绑定的控件上设置RelativeSource而不是其父控件.

即绑定到UserControl的属性:

Binding Path=PropertyName, 
        RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}
Run Code Online (Sandbox Code Playgroud)

鉴于目前看到数据绑定有多么困难,即使您发现该设置RelativeSource={RelativeSource Self}当前有效,也值得记住这一点:)


jon*_*ham 5

再说一点:没有'get','set'的财产将无法受到限制

我就像提问者的情况一样面对案件.我必须具备以下内容才能使绑定正常工作:

//(1) Declare a property with 'get','set' in code behind
public partial class my_class:Window {
  public String My_Property { get; set; }
  ...

//(2) Initialise the property in constructor of code behind
public partial class my_class:Window {
  ...
  public my_class() {
     My_Property = "my-string-value";
     InitializeComponent();
  }

//(3) Set data context in window xaml and specify a binding
<Window ...
DataContext="{Binding RelativeSource={RelativeSource Self}}">
  <TextBlock Text="{Binding My_Property}"/>
</Window>
Run Code Online (Sandbox Code Playgroud)

  • 如果没有"获取"和"设置",你怎么能拥有一个属性?这不是一个领域而不是财产吗? (7认同)