2010-03-02 16 views
30

Bastante simple, pero parece que no puede encontrar una respuesta completa aquí ...WPF Enlazar a miembros de la clase en el código detrás de la pregunta

necesito DataBind en XAML a una propiedad de un miembro de la clase de código subyacente.

<Window x:Class="Main"> 
    <customcontrol Name="View" IsChecked="{Binding ElementName=RecordProp, Path=IsViewChecked}" /> 
... 

Cuando el código detrás se ve así:

class Main 
{  
    ... 
    private Record _record; 
    public Record RecordProp 
    { 
     get { return _record; } 
    } 
    ... 
} 


class Record 
{ 
    public bool IsViewChecked 
    { 
    get; set; 
    } 
} 

Lo que tengo ahora no funciona, ¿qué estoy haciendo mal?

Respuesta

26

Ruta necesita una fuente de ir en contra (Fuente, DataContext, RelativeSource, ElementName). ElementName solo se puede usar para referirse a elementos declarados en XAML por su x: Name. Prueba este lugar para apuntar a su ventana como la fuente:

IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=RecordProp.IsViewChecked}" 
3

La vinculación de datos no funcionará contra campos privados. Está destinado a propiedades públicas en su lugar. Intente exponer públicamente el valor _record y agréguese a eso en su lugar.

Referencia - http://msdn.microsoft.com/en-us/library/ms743643.aspx

+0

La propiedad pública no tuvo ningún efecto. – jaws

+0

@ user258651 Creo que también necesita actualizar el contexto de enlace para que la ventana principal lo devuelva por defecto a la clase principal. Ha pasado un tiempo desde que miré eso sin embargo. – JaredPar

29

Lo que estoy viendo aquí es que el nombre de clase de su ventana es Main, que ha agregado una propiedad RecordProp a ella, y que está ahora intenta enlazar a la propiedad IsChecked del elemento denominado RecordProp. Creo que estás un poco confundido sobre cómo funcionan los nombres.

Agregar el atributo x:Name a un elemento XAML crea un campo en la clase de ventana con ese nombre. Esto le permite hacer referencia a los elementos con nombre en su código, y probablemente le haya llevado a pensar que el enlace puede hacer lo mismo.

Pero así no es cómo el enlace encuentra elementos con nombre. El atributo x:Nametambién toma el objeto que crea el elemento XAML y lo registra con ese nombre en el namescope de la ventana. (Consulte MSDN's article on XAML namescopes.) Esto es lo que observa el enlace para resolver los nombres de los elementos. Como nunca agregará el objeto al namescope, establecer la propiedad ElementName en un enlace no lo encontrará.

Hay un par de cosas que posiblemente podría hacer. Si realmente desea enlazar a una propiedad de la ventana, se puede dar a la ventana de un nombre y enlazar con el establecimiento a través de una ruta de propiedad:

<Window x:Name="MainWindow" x:Class="Main"> 
... 
    <customcontrol Name="View" IsChecked=" 
       {Binding ElementName=MainWindow, 
        Path=RecordProp.IsViewChecked}" /> 

aún más simple es simplemente establecer el contexto de datos en el constructor:

DataContext = this; 

Una vez hecho esto, sólo puede unirse a la RecordProp propiedad (y cualquier otra propiedad de la ventana) de esta manera:

<customControl Name="View" IsChecked={Binding RecordProp.IsChecked}/> 

Por supuesto, eso no va a funcionar si el yo Necesita que el contexto de datos de la ventana se establezca en otra cosa.

Otra posibilidad es aplicar la propiedad como esta:

public Record RecordProp 
{ 
    get { return (Record)Resources["RecordProp"]; } 
    set { Resources["RecordProp"] = value; } 
} 

Puede enlazar a esta utilizando (por ejemplo) Binding {DynamicResource RecordProp}, Path=IsChecked".Dado que es un recurso dinámico, si algo externo a la ventana establece la propiedad RecordProp de la ventana, los enlaces se actualizarán, algo que no ocurrirá si solo hace que RecordProp sea una propiedad (a menos que implemente una notificación de cambio).

+0

Una nota, DataContext debe establecerse no en el constructor de Windows, sino en el controlador de eventos Loaded. Establecer esto en un constructor no funcionó para mí para ObservableCollection cuando lo llené dentro del evento Loaded. –

+2

En lugar de configurar el 'DataContext' de' Windows' del código, simplemente puede agregar esto al 'XAML' de Windows '' DataContext = "{Binding RelativeSource = {RelativeSource Self}}' –

6

Creo que tengo una respuesta más simple que las indicadas hasta ahora. Basta con añadir esto a la declaración de la ventana (la primera etiqueta) en XAML:

x:Name="this" 

A continuación, puede DataBind así:

<customcontrol Name="View" IsChecked="{Binding ElementName=this, Path=RecordProp.IsViewChecked}" /> 

he comprobado para ver si C# se queja de que ya existe un " esto, "y no fue así, supongo que porque ambos se refieren al mismo objeto exacto.

Esta es la solución que utilicé cuando me encontré con el mismo problema, y ​​encontré que es muy intuitivo de usar.

+0

¿Hay alguna razón para no hacerlo? para hacerlo de esta manera? He intentado las otras soluciones sin éxito. Esta es la única forma en que he podido hacer que funcione con mis habilidades de novato C# –

+1

Si rechazaste, por favor comenta por qué piensas que esto es un mala solución. – JoeCool

Cuestiones relacionadas