2012-02-15 13 views
13

Como titulado, He visto parejas de la pregunta similar this o this en SO, pero no veo una solución para ello.¿Es posible vincular propiedad de código subyacente sin configurar DataContext?

Sé que si tengo que enlazar con el código beind, necesito fijar Datacontext = this

Pero mi problema es que mi DataContext ya unirse a mi modelo de vista, pero yo quiero hacer alguna manipulación de interfaz de usuario con el uso de comandos que se define en el código-beind.

¿Es posible enlazarlo en xaml? ¿Si es así, cómo?

EDIT: se trató de la siguiente manera:

<Window x:Class="WpfApplication3.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Window1" Height="300" Width="300" x:Name="_Root"> 
<Grid x:Name="hellogrid"> 
    <TextBlock x:Name="myTextBlock" Text="AAAA"/> 
    <Button Margin="82,119,121,120" Name="button2" Content="{Binding Path=Text, ElementName=myTextBlock}"/> 
    <Button Margin="82,72,121,0" Name="button3" Content="{Binding Path=MyText, ElementName=_Root}" Height="23" VerticalAlignment="Top" /> 
</Grid> 

Y de código subyacente:

public partial class Window1 : Window 
{ 
    public string MyText { get; set; } 

    public Window1() 
    { 
     InitializeComponent(); 
     MyText = "ABC"; 
    } 
} 

pude ver el Button2 muestra AAAA, pero Button3 muestra nada ...

+0

favor ver mi respuesta actualizada, Acabo de prueba y la forma en que ates su button3 propiedad Content funciona bien, sólo tiene que poner en práctica la notificación de cambios si es necesario cambiar esa propiedad MyText en tiempo de ejecución ... –

Respuesta

14

EDITAR

La mejor solución OMI es el posted por @Saad Imran en este SO question ...

Con esta solución, todo lo que tiene que hacer es nombrar su ventana y vincular a una propiedad en su XAML será tan fácil como esto {Binding ElementName=MyWindowName, Path=MyText}

Entonces, lo que está haciendo con Content="{Binding Path=MyText, ElementName=_Root}" es exactamente correcto y su propiedad de Contenido de botón está vinculada a la propiedad MyText pero lo único que falta es notificación de cambio (necesita implementar la interfaz INotifyPropertyChanged) para que cuando configure MyText propiedad de ABC MyText = "ABC"; no se envía ninguna notificación de cambio ...

manera fácil de probar esto es estableciendo la propiedad MyText explícitamente como tales:

private string myText = "ABC"; 
public string MyText 
{ 
    get { return myText; } 
    set { myText = value; } 
} 

o establecer en el constructor antes InitializeComponent() se llama:

MyText = "ABC"; 
InitializeComponent(); 

Si usted hace que usted notará que el botón tendrá ABC como su contenido, sino a cambios myText propiedad no afectará el contenido botón porque no hay una notificación de cambio de ...

+0

Ahhh, ya veo, es por eso que me he perdido. Funciona perfecto ahora. ¡Muchas gracias! –

5

Claro, puedes usar ElementName:

<Window Name="root" 
     Class="..." 
     ...> 

    ... 

    <TextBox Text="{Binding Path=Foo, ElementName=root}" /> 

También puede hacerlo con RelativeSource, pero la sintaxis es más feo ...

+0

Extraño, probé '' ElementName' y 'Binding Path = Foo, RelativeSource = {RelativeSource Self}', pero ninguno de los dos funciona. Estoy usando WPF 3.5, ¿Importa? –

+2

@KingChan, es porque estableces la propiedad MyText * después de * la llamada a 'InitializeComponent', por lo que el valor ya se ha recuperado antes de cambiarlo. Como su clase no implementa 'INotifyPropertyChanged', y su propiedad no es una propiedad de dependencia, el motor de enlace no tiene forma de saber que el valor ha cambiado, por lo que no actualiza el contenido del botón. –

9

Por supuesto

Hay muchos tipos de enlaces.La más básica se une a una propiedad en la DataContext, que generalmente se hereda de un objeto padre

<DataTemplate DataType="{x:Type MyModel}"> 
    <!-- DataContext is object of type MyModel --> 
    <local:MyView /> 
</DataTemplate> 

O

<Window x:Name="MyWindow"> 
    <!-- DataContext Inherited from Window --> 
    <TextBlock Text="{Binding SomeProperty}" /> 
</Window> 

donde

var SomeObject = new SomeModel(); 
SomeObject.SomeProperty = "Test"; 
myWindow.DataContext = SomeObject; 

Otros tipos de unión incluyen ElementName, donde puede especificar el elemento de la IU de destino para usar como fuente de datos para el enlace

<StackPanel> 
    <CheckBox x:Name="SomeCheckBox" /> 
    <TextBlock Text="{Binding ElementName=SomeCheckBox, Path=IsChecked}" /> 
</StackPanel> 

o

<local:MyUserControl x:Name="SomeUserControl"> 
    <Button Command="{Binding ElementName=SomeUserControl, Path=DataContext.SaveCommand}" /> 
</local:MyUserControl > 

O RelativeSource, que le permite encontrar un objeto con respecto al objeto actual a utilizar como origen de datos

<Window Title="Test"> 
    <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=Title}" /> 
</Window> 

o

<local:MyUserControl> 
    <Button Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}, Path=DataContext.SaveCommand}" /> 
</local:MyUserControl > 

Y TemplateBinding , que se une es un atajo a RelativeSource unión que se une a un objeto de plantilla

<Button Content="Test"> 
    <Button.Template> 
     <ControlTemplate TargetType="{x:Type Button}"> 
      <TextBlock Text="{TemplateBinding Content}" /> 
     </ControlTemplate> 
    </Button.Template> 
</Button> 
+0

Gracias por la referencia Lo tengo trabajando con tu RelativeSource también. Pero extraño, ¿cómo es que no necesito INotifyPropertyChanged cuando uso 'RelativeSource AncestorType = {x: Type Window}'? –

+1

Esta es una descripción general de la vinculación en WPF, no una respuesta a su pregunta ... –

+0

@DeanKuga No tenía claro cuál era la pregunta real antes de agregar el código, y lo leyó como "¿Puedo vincularme a algo? sin especificarlo en el DataContext ". Parecía una pregunta bastante amplia, así que escribí una respuesta amplia :) Una vez que se agregó el código, pude ver claramente lo que OP intentaba lograr, pero para entonces ya se había publicado una respuesta que contenía la información que necesitaba. – Rachel

Cuestiones relacionadas