Soru XAML'de Kendime / 'Buna' Bağlanma


Basit WPF / XAML sorusu. XAML'de, Öz / bu nesneyi belirli bir bağlamda nasıl referans gösterebilirim? Ana pencere, bir kontrol ve pencerenin kodlanmış bir C # özelliği ile çok temel bir uygulamada, kontrolün bir özelliğini pencerenin el ile kodlanmış özelliğine bağlamak istiyorum.

Kodda, bu çok kolaydır - Window'un yapıcısında şunu ekledim:

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

Açıkçası, ButtonWidth adlı bir özelliğe ve button1 adlı bir kontrole sahibim. Bunu XAML'de nasıl yapacağımı anlayamıyorum. Aşağıdaki örnek gibi çeşitli girişimler işe yaramadı:

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

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

vb

Teşekkürler


44
2017-10-01 09:01


Menşei




Cevaplar:


İlk önce Bağlantınızda RelativeSource ve Path arasında bir virgül kullanın:

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

İkincisi, RelativeSource Düğmeye bağlanır. Düğmenin ButtonWidth adlı bir özelliği yoktur. Ebeveyn kontrolüne bağlanmanız gerektiğini tahmin ediyorum.

Bu RelativeSource bağlayıcısını deneyin:

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

69
2017-10-01 09:07



Bu yazı için çok teşekkür ederim. Bana çok yardımcı oldu! 3 saat sonra iyi bir çözüm arıyordum. - Mr Tangjai
Bir DataGrid'im var. Burada, Kullanıcı, ContextMenu'nun MenuItem'in Komut'larına, CommandParameter = "{Binding ElementName = MyDataGrid, Path = SelectedItems}" adlı bir InputBinding'ın KeyBinding'i üzerinden erişirse, SelectedItems'i Bound ICommand'a iletir. Ancak, ContextMenu aracılığıyla erişilirse null geçilir. CommandParameter = "{SelectedItems} Bağlama", "{Binding ElementName = MyDataGrid, Path = SelectedItems}", "{Binding RelativeSource = {RelativeSource FindAncestor, AncestorType = {x: Type DataGrid}}, Path = SelectedItems}" komutlarını denedim. . Komuttan önce CommandParameter'ı ayarladım. - Tom


RelativeSource ve benzeri ile uğraşmak zorunda kalmanın bir yolu root XAML öğesini adlandırmaktır:

<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'i ayarlamak isterseniz bunu da yapabilirsiniz:

<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>

Bu RelativeSource bağlama tüm karmaşıklıkları hatırlamak zorunda kalmamak için iyi bir hile olarak bulmak.


27
2017-11-29 22:08





Bence aradığın şey şudur:

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

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

>

25
2017-11-07 17:48



Doğrulanmış hâlâ <Page> ana öğesinde Windows 10 uygulamasında çalışır. - Lavamantis


Adlandırma ile ilgili sorun XAML root element, eğer projenizdeki tüm kökler için aynı ismi (yani "_this", "Root", vb.) kullanma alışkanlığınıza girerseniz, iç içe geçmiş şablonlarda geç bağlama yanlış öğeye erişebilir. . Çünkü {Binding}  ElementName=... bir kullanılır Templateadlarını çalıştırarak, çalışma zamanında çözülür NameScope İlk maça kadar ağaç bulunur.

Clint'in çözümü kök elementini isimlendirmekten kaçınır, ancak kök elementi kendi başına ayarlar. DataContextDataContext'in veri için gerekli olup olmadığı bir seçenek olmayabilir. Aynı zamanda, bir öğeye yalnızca ona erişim sağlama amacıyla başka bir bağlanma getirmek için biraz ağır görünüyor. Daha sonra, erişim artık gerekli değilse, {Binding} dağınıklık olacak: erişim için sorumluluk, hedefe ve bağlayıcıya aittir.

Buna göre, XAML kök öğesine ad vermeksizin erişmek için basit bir biçimlendirme uzantısıdır:

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>

Sonuç:

enter image description here


N.B.

netlik için, hayır clr-namespace kullanılır, ancak burada gösterilen XAML'nin aslında erişim için çalıştığını unutmayın. global ad alanı (VS2013 tasarımcısı şikayetçi olsa da)


3
2017-12-19 22:18





Ne yazık ki, "ElementName = .." ile kök öğesinin adlandırılması, {RelativeSource Self} burada desteklenmediği için UWP ile tek yol gibi görünüyor.

İşin tuhafı, bu, adın düzende geçersiz kılınması durumunda çalışır, ör.

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

sonra

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

</Page>

BTW, Windows 10 aynı düzende farklı öğeler için aynı dahili ad kullanıldığında bir hata (Windows 8.1'de mevcut).

Yine de, bana daha mantıklı ve daha güvenli göründüğünden, {RelativeSource Self} kullanmayı tercih ederim.


0
2018-02-15 02:17