2010-10-01 73 views
42

簡單的WPF/XAML問題。在XAML中,我如何在給定的上下文中引用Self/this對象?在一個帶有主窗口,一個控件和窗口的編碼C#屬性的非常基本的應用程序中,我想要將控件的屬性綁定到窗口的手形編碼屬性。在XAML中綁定到Self /'this'

在代碼中,這是很容易 - 在窗口的構造函數,我添加了這個:

Binding bind = new Binding(); 
bind.Source = this; 
bind.Path = new PropertyPath("ButtonWidth"); 
button1.SetBinding(WidthProperty, bind); 

很顯然,我有一個名爲buttonWidth屬性,以及一個名爲button1控件。我無法弄清楚如何在XAML中做到這一點。像下面的例子中各種嘗試都沒有奏效:

<Button x:Name="button1" Width="{Binding Source=Self Path=ButtonWidth}"/> 

<Button x:Name="button1" Width="{Binding RelativeSource={RelativeSource Self} Path=ButtonWidth}"/> 

感謝

回答

66

首先使用您綁定的RelativeSource和路徑之間的逗號:

<Button x:Name="button1" Width="{Binding RelativeSource={RelativeSource Self}, 
           Path=ButtonWidth}"/> 

其次, RelativeSource綁定到Button。 Button沒有名爲ButtonWidth的屬性。我猜你需要綁定到你的父母控制。

那麼試試這個的RelativeSource綁定:

<Button x:Name="button1" Width="{Binding RelativeSource= 
    {RelativeSource FindAncestor, AncestorType={x:Type YourNamespace:YourParentControl}}, 
    Path=ButtonWidth}"/> 
+0

非常感謝你這篇文章。這對我幫助很大!我一直在尋找一個3小時的好解決方案。 – 2017-03-17 01:12:32

+0

我有一個DataGrid,如果用戶通過其CommandParameter =「{Binding ElementName = MyDataGrid,Path = SelectedItems}」的InputBinding的KeyBinding訪問其內聯ContextMenu的MenuItem的Command中的一個,它將把SelectedItems傳遞給Bound ICommand。但是,如果通過ContextMenu訪問它,則會傳遞null。我試過CommandParameter =「{Binding SelectedItems}」,「{Binding ElementName = MyDataGrid,Path = SelectedItems}」,「{Binding RelativeSource = {RelativeSource FindAncestor,AncestorType = {x:Type DataGrid}},Path = SelectedItems}」 。我在Command之前設置了CommandParameter。 – Tom 2017-05-08 21:36:24

26

一個我避開不必處理的RelativeSource之類的方法是名稱的根XAML元素:

<Window x:Class="TestApp2.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525" 
    x:Name="_this" 
    > 
    <Grid> 
     <Button x:Name="button" Width="{Binding ElementName=_this,Path=ButtonWidth}" /> 
    </Grid> 
</Window> 

如果你想設置DataContext你也可以做到這一點:

<Window x:Class="TestApp2.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525" 
    x:Name="_this" 
    > 
    <Grid DataContext="{Binding ElementName=_this}">   
     <Button x:Name="button" Width="{Binding Path=ButtonWidth}" /> 
    </Grid> 
</Window> 

我覺得這是一個很好的竅門,不必記住注意RelativeSource綁定的所有複雜性。

23

我想你正在尋找的是這樣的:

<Window x:Class = "blah blah all the regular stuff" 

DataContext="{Binding RelativeSource={RelativeSource Self}}" 

> 
+0

已驗證仍然適用於主要元素中的Windows 10應用程序。 – Lavamantis 2016-09-26 20:43:49

3

與命名XAML根元素的問題是,如果你進入使用相同名稱的習慣(即「_this」 「根」等),那麼在嵌套模板中的後期綁定可能會訪問錯誤的元素。這是因爲,在Template中使用時,通過在NameScope樹上行走,在運行時解析名稱,直到找到第一個匹配項。

Clint的解決方案避免了命名根元素,但是它將根元素設置爲自己的DataContext,如果數據需要DataContext,這可能不是一個選項。爲了提供對元素的訪問權限,爲了在元素上引入另一個綁定也似乎有些過分。後來,如果不再需要訪問,那麼{Binding}將變得混亂:訪問責任正確地屬於目標和綁定。

因此,這裏是一個簡單的標記擴展而不命名它訪問XAML根元素:

using System.Xaml; 
using System.Windows.Markup; 

public sealed class XamlRootExtension : MarkupExtension 
{ 
    public override Object ProvideValue(IServiceProvider sp) 
    { 
     var rop = sp.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider; 
     return rop == null ? null : rop.RootObject; 
    } 
}; 

XAML:

<Window x:Class="MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:global="clr-namespace:"> 

    <TextBlock Text="{Binding Source={global:XamlRoot},Mode=OneTime}" /> 

</Window> 

結果:

enter image description here


n.b.

爲清楚起見,沒有clr-namespace被使用,但請注意,這裏顯示的XAML來訪問global命名空間不實際工作(雖然VS2013設計師抱怨)

0

不幸的是,命名爲「的ElementName =根元素。 「似乎是UWP的唯一方式,因爲{RelativeSource Self}在那裏不受支持。

奇怪的是,當名稱在佈局中被覆蓋時,這仍然有效。

<UserControl x:Class="Path.MyClass" x:Name="internalName"> 
    <Border Background={Binding Path=Background, ElementName=internalName}" ... 

然後

<Page> 
    <local:MyClass x:Name=externalName /> 

</Page> 

順便說一句,視窗10固定的誤差(存在於Windows 8.1中)中,當相同的內部名稱用於在相同的佈局不同的元素。

不過,我寧願使用{RelativeSource Self},因爲它對我來說似乎更合理和安全。