2009-10-28 23 views
22

Actualmente estoy trabajando con un control de usuario de WPF (el elemento raíz de mi archivo XAML es "UserControl"), que sé que se aloja dentro de una ventana. ¿Cómo puedo acceder a una propiedad de la ventana utilizando el enlace de datos?¿Qué hace exactamente "RelativeSource FindAncestor" de WPF Data Binding?

¿Alguien sabe por qué simplemente

<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Window}}" Path="..." /> 

no funciona? El mensaje de error que recibo es:

System.Windows.Data Advertencia: 4: No se puede encontrar el origen del enlace con la referencia 'RelativeSource FindAncestor, AncestorType =' System.Windows.Window ', AncestorLevel =' 1 ''.

Editar: Terminé usando una variación en el enfoque de ArsenMkrt, así que acepté su respuesta. Sin embargo, todavía estoy interesado en descubrir por qué FindAncestor no "solo funciona".

+2

dice que ha variado su respuesta, ¿puede publicar lo que realmente hizo? – Miles

+0

Tenga en cuenta que estaba buscando una solución a este problema en el contexto del patrón MVVM. La propiedad de la ventana a la que quería enlazar era en realidad una propiedad del ViewModel de la ventana. – user200783

+1

ArsenMkrt sugirió crear una propiedad en el UserControl y enlazar a eso, luego a su vez (en XAML) vinculando esta propiedad a la propiedad deseada de la Ventana. Sin embargo, con el patrón MVVM, UserControl nunca apareció en XAML, por lo que la segunda parte no fue posible. – user200783

Respuesta

15

La mejor manera es dar un nombre al control de usuario

crear dependencia MyProperty propiedad de control de usuario con dos vías de unión y se unen en la ventana principal, que se unen en el control de usuario como esto

<UserControl x:Name = "myControl"> 
    <Label Content={Binding ElementName= myControl, Path=MyProperty}/> 
</UserControl> 
+0

Pero quiero enlazar a una propiedad en la ventana contenedora (definida en otro archivo XAML), no en el UserControl. – user200783

+0

Que será mejor tener propiedad en usercontrol y vincular esa propiedad con la propiedad de ventana –

+2

¿Se puede crear una propiedad de dependencia en UserControl? ¿no agregas usercontrol en la ventana?

0

I Think se debe ajustar el modo = "OneWayToSource" de esta manera:

<TextBox Text="{Binding RelativeSource={RelativeSource FindAncestor ,AncestorType={x:Type Grid}},Path=BackGround , Mode=OneWayToSource , UpdateSourceTrigger = PropertyChanged}" /> 
4

Si usted está tratando de 'escapar' de una o ItemsControlDataGridView para obtener un Window, puede encontrar que AncestorType de x:Type Window no funciona. O al menos no parece ...

Si este es el caso, probablemente estés ejecutando Blend o Visual Studio y esperando que los datos estén visibles en el momento del diseño, lo cual no ocurrirá porque VS + Blend ambos crea sus propias instancias que no son realmente Windows. Funcionará perfectamente en tiempo de ejecución, pero no durante el modo de diseño.

Hay un par de cosas que puede hacer:

  • Wrap en un control de usuario

  • Aquí hay una solución alternativa que he llegado con. Tiene una ventaja en cuanto a que no hace referencia directamente a un UserControl o Window, por lo que si cambia el contenedor principal, su código no se romperá.

    <Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:views="clr-namespace:MyWPFApplication.Views" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     
    x:Class="MyWPFApplication.Views.UPCLabelPrinterWindow" 
    mc:Ignorable="d" 
    x:Name="LayoutRoot" 
    Title="UPCLabelPrinterWindow"> 
    
    <views:DataContextWrapper> 
        <DockPanel> 
         ... 
        </DockPanel> 
    </views:DataContextWrapper> 
    

Dónde DataContextWrapper es sólo una cuadrícula

namespace MyWPFApplication.Views { 
    public class DataContextWrapper : Grid 
    { 

    } 
} 

A continuación, cuando se enlaza a hacerlo:

<TextBlock Text="{Binding="{Binding DataContext.SomeText, 
    RelativeSource={RelativeSource AncestorType={x:Type views:DataContextWrapper}, 
    Mode=FindAncestor}}" /> 

Nota: si desea unirse a una propiedad en la ventana en sí es más complicado y probablemente deberías enlazar a través de una propiedad de dependencia o algo así. Pero si está utilizando MVVM, esta es una solución que encontré.

+0

En mi caso 'AncestorType = {x: Type Window}' fue muy útil, porque 'AncestorType = UserControl' de alguna manera no apuntó a mi ventana, aunque normalmente lo hace. – LuckyLikey

Cuestiones relacionadas