no se puede vincular a la propiedad de dependencia propia

Tengo un Downloader, que tiene una propiedad de progreso, que es:

    public static readonly DependencyProperty ProgressProperty = DependencyProperty.Register("Progress", typeof(int), typeof(Downloader), new PropertyMetadata(0, new PropertyChangedCallback(OnProgressChange)));

    public int Progress
    {
        get { return (int)this.GetValue(ProgressProperty); }
        private set { this.SetValue(ProgressProperty, value); }
    }

    private static void OnProgressChange(DependencyObject @object, DependencyPropertyChangedEventArgs e)
    {
        Downloader d = @object as Downloader;
        if (d.PropertyChanged != null) d.PropertyChanged(d, new PropertyChangedEventArgs("Progress"));
    }

Cuando trato de consumirlo en otra clase xaml (m_downloader es un campo privado de tipo Downloader):

<sdk:Label Height="24" HorizontalAlignment="Left" Margin="360,12,0,0" Name="ProgressLabel" VerticalAlignment="Top" Width="38" Content="{Binding Path=m_downloader.Progress, StringFormat='\{0\} %'}" />

no pasa nada. Durante la depuración, puedo ver que d.PropertyChanged siempre es nulo. ¿Cómo hacer que funcione para mostrar el progreso en la etiqueta?

EDIT 1:

m_downloader funciona así (después de un cambio temporal en la propiedad):

public partial class AudioPlayer : UserControl
{
    public AudioPlayer()
    {
        m_downloader = new Downloader();
        InitializeComponent();
    }
    ...
    public Downloader m_downloader {get; private set;}
}

EDIT 2:

Hice el enlace en Blend, cambió el xaml a esto:

<UserControl x:Name="audioPlayer" x:Class="Media.Controls.AudioPlayer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="125" d:DesignWidth="410" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">

<Grid x:Name="LayoutRoot" Background="White">
    ...
    <sdk:Label Height="24" HorizontalAlignment="Left" Margin="337,12,0,0" Name="ProgressLabel" VerticalAlignment="Top" Width="61" Content="{Binding m_downloader.Progress, ElementName=audioPlayer, Mode=OneWay}" />
    ...
</Grid>
</UserControl>

Por qué ElementName se establece en el nombre de anidación, en lugar del anidado? No tiene sentido para mí... Pero está funcionando después de este cambio.

preguntado el 03 de mayo de 12 a las 20:05

si m_downloader es privado, no puede enlazarlo. Tiene que ser público. -

Cambié a público, pero aún no tuve suerte... -

¿Está seguro de que DataContext está configurado correctamente, por lo que puede enlazar con m_downloader? -

No estoy configurando DataContext... ¿Dónde debo hacerlo? -

Entonces, ¿dónde se encuentra EXACLTY m_downloader? Código postal. -

1 Respuestas

Como busca una explicación, el mecanismo de enlace funciona así:

  1. El mecanismo de vinculación depende de dos cosas: la ruta y la fuente en la vinculación

  2. La ruta en su caso es "m_Downloader.Progress", y si la fuente no se establece explícitamente, el enlace recurre al uso de DataContext en la etiqueta

  3. Si no hay un DataContext establecido en la etiqueta, busca un DataContext en el árbol visual.

  4. Puede configurar la fuente explícitamente usando {Binding Source=...} o {Binding ElementName=...}

Por ejemplo, lo siguiente no funcionará:

<sdk:Label 
   x:Name="ProgressLabel"
   Content="{Binding Path=Progress}" />

Esto se debe a que no hay una fuente y DataContext no está configurado.

Puede configurar esto en el código usando:

ProgressLabel.DataContext = m_Downloader

Alternativamente, es posible que desee vincular en relación con el objeto de anidamiento.

<sdk:Label
   Content="{Binding m_Downloader.Progress}" />

Sin embargo, esto no funcionará como

  1. m_Downloader no es público, y

  2. m_Downloader ni siquiera es una propiedad

  3. DataContext no está configurado.

Para resolver esto, utilice lo siguiente:

Descargador público Descargador {get; conjunto;|

public void InitializeComponent() { // ...

 // set DataContext to nesting object
 ProgressLabel.DataContext = this; 

}

Si no desea establecer DataContext en el código, puede establecer la fuente explícitamente. Dado que AudioPlayer tiene un nombre de elemento

<UserControl x:Name="AudioPlayer" ... />

Puede hacer referencia a él en su encuadernación

<sdk:Label
   Content="{Binding m_Downloader.Progress, ElementName=AudioPlayer}" />

Finalmente, también puede hacer esto configurando DataContext en AudioPlayer a sí mismo.

<UserControl
   DataContext="{Binding RelativeSource={RelativeSource Self}}" />

<sdk:Label
   Content="{Binding m_Downloader.Progress}" />

contestado el 03 de mayo de 12 a las 23:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.