¿Qué hace exactamente "RelativeSource FindAncestor" de WPF Data Binding?
data-binding xaml (3)
Creo que debes SET Mode = "OneWayToSource" De esta manera:
<TextBox Text="{Binding RelativeSource={RelativeSource FindAncestor ,AncestorType={x:Type Grid}},Path=BackGround , Mode=OneWayToSource , UpdateSourceTrigger = PropertyChanged}" />
Actualmente estoy trabajando con un control de usuario de WPF (el elemento raíz de mi archivo XAML es "UserControl"), que sé que está alojado dentro de una ventana. ¿Cómo puedo acceder a una propiedad de la ventana utilizando el enlace de datos?
¿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".
La mejor forma es darle un nombre a UserControl
Cree la propiedad de dependencia MyProperty en UserControl con enlace bidireccional y conéctelo en la ventana principal, luego de vincular UserControl como este
<UserControl x:Name = "myControl">
<Label Content={Binding ElementName= myControl, Path=MyProperty}/>
</UserControl>
Si intenta ''escapar'' de ItemsControl
o DataGridView
para acceder a una Window
es posible que descubra que AncestorType of 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 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 puedes hacer:
Ajustar en un UserControl
Aquí hay una solución alternativa que se me ocurrió. Tiene una ventaja en cuanto a que no está haciendo referencia directamente a
UserControl
oWindow
, por lo que si cambia el contenedor primario, 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>
Donde DataContextWrapper
es solo una Cuadrícula
namespace MyWPFApplication.Views {
public class DataContextWrapper : Grid
{
}
}
Luego, cuando te unes, haces esto:
<TextBlock Text="{Binding="{Binding DataContext.SomeText,
RelativeSource={RelativeSource AncestorType={x:Type views:DataContextWrapper},
Mode=FindAncestor}}" />
Nota: si desea vincularse a una propiedad ON Window, es más complicado y probablemente debería vincularse a través de una propiedad de dependencia o algo así. Pero si está utilizando MVVM, esta es una solución que encontré.