Problema con el enlace DependencyProperty

Creé un pequeño control de explorador de archivos:

       

Con el siguiente código detrás:

 public partial class FileBrowserControl : UserControl { public ICommand BrowseCommand { get; set; } //The dependency property public static DependencyProperty SelectedFileProperty = DependencyProperty.Register("SelectedFile", typeof(string),typeof(FileBrowserControl), new PropertyMetadata(String.Empty)); public string SelectedFile { get{ return (string)GetValue(SelectedFileProperty);} set{ SetValue(SelectedFileProperty, value);}} //For my first test, this is a static string public string Filter { get; set; } public FileBrowserControl() { InitializeComponent(); BrowseCommand = new RelayCommand(Browse); Control.DataContext = this; } private void Browse() { SaveFileDialog dialog = new SaveFileDialog(); if (Filter != null) { dialog.Filter = Filter; } if (dialog.ShowDialog() == true) { SelectedFile = dialog.FileName; } } } 

Y lo uso así:

  

(SelectedFile es propiedad del ViewModel del usercontrol usando este control)

Actualmente, el problema es que cuando hago clic en Examinar, el cuadro de texto de usercontrol se actualiza correctamente, pero la propiedad SelectedFile del control principal de viewmodel no está configurada (no hay llamadas a la propiedad set).

Si configuro el modo del enlace a TwoWay, obtuve esta excepción:

 An unhandled exception of type 'System.StackOverflowException' occurred in Unknown Module. 

Entonces, ¿qué hice mal?

El principal problema es que configura el DataContext de UserControl para sí mismo en su constructor:

 DataContext = this; 

No debería hacer eso, porque rompe cualquier enlace basado en DataContext, por ejemplo, a una instancia de modelo de vista en el valor heredado de DataContext.

En cambio, cambiaría el enlace en el XAML de UserControl de esta manera:

  

Ahora, cuando usa UserControl y escribe un enlace como

  

la propiedad SelectedFile se vincula a una propiedad SelectedFile en su modelo de vista, que debe estar en el DataContext heredado de un control principal.

Usando esto:

  

El DataContext de FileBrowserControl ya se ha configurado a sí mismo, por lo tanto, efectivamente se está pidiendo que se enlace al SelectedFile donde DataContext es FileBrowserControl, no el ViewModel padre.

Dale a tu vista un nombre y utiliza un enlace ElementName en su lugar.

 SelectedFile="{Binding DataContext.SelectedFile, ElementName=element}" 

Nunca configure DataContext de UserControl dentro de usercontrol:

ESTO ESTÁ MAL:

 this.DataContext = someDataContext; 

porque si alguien usa tu usercontrol, es una práctica común establecer su contexto de datos y está en conflicto con lo que has establecido previamente

  

¿Cuál se usará? Bueno, eso depende…

Lo mismo se aplica a la propiedad Nombre. no debe establecer el nombre para UserControl de esta manera:

  

porque está en conflicto con

  

SOLUCIÓN:
En su control, simplemente use RelativeSource Mode = FindAncestor:

  

A su pregunta sobre cómo se hacen todos esos controles de terceros: usan TemplateBinding. Pero TemplateBinding solo se puede usar en ControlTemplate. http://www.codeproject.com/Tips/599954/WPF-TemplateBinding-with-ControlTemplate

En usercontrol, xaml representa el contenido de UserControl, no ControlTemplate /