way two tutorial que español data context c# wpf data-binding methods

c# - two - Enlace de datos a un método en WPF



wpf binding types (5)

Estoy teniendo problemas para TextBox.Text datos de una propiedad TextBox.Text con el método de un objeto. La idea es permitirle al usuario escribir en un TextBox un nombre de archivo y luego tener un TextBlock que produzca la extensión de ese archivo.

class GetFileInfo { public string GetFileExtension(string fileName) { return Path.GetExtension(fileName); } }

Aquí está mi XAML:

<Window.Resources> <ObjectDataProvider x:Key="getFileInfo" MethodName="GetFileExtension" ObjectType="{x:Type local:GetFileInfo}"> <ObjectDataProvider.MethodParameters> <sys:String>abc.text</sys:String> </ObjectDataProvider.MethodParameters> </ObjectDataProvider> </Window.Resources> <StackPanel> <TextBox Name="textBox1"> <TextBox.Text> <Binding Source="{StaticResource getFileInfo}" Path="MethodParameters[0]" BindsDirectlyToSource="True" UpdateSourceTrigger="PropertyChanged" /> </TextBox.Text> </TextBox> <TextBlock Name="textBlock1" Text="{Binding Source={StaticResource getFileInfo}}"/> </StackPanel>

Por alguna razón, no está haciendo nada. ¿Alguno de ustedes podría señalar cuáles pueden ser las razones? Esto es lo que veo en el diseñador y cuando ejecuto la aplicación:

texto alternativo http://img64.imageshack.us/img64/6922/f0rki14feo3oa3groxm5kgm.png

Y esto es lo que sucede cuando intento configurar otro texto en tiempo de ejecución:

alt text http://img684.imageshack.us/img684/1057/b52pnq1dm4i23qivizvpaqq.png Aquí está el error dado por el depurador al intentar establecer otro texto en tiempo de ejecución:

System.Windows.Data Error: 8: No se puede guardar el valor del objetivo de nuevo a la fuente. BindingExpression: Path = MethodParameters [0]; DataItem = ''ObjectDataProvider'' (HashCode = 2207369); el elemento objetivo es ''TextBox'' (Name = ''textBox1''); target property es ''Text'' (tipo ''String'') ArgumentException: ''System.ArgumentException: objeto de tipo'' MS.Internal.Data.PropertyPathWorker + IListIndexerArg ''no se puede convertir a tipo'' System.Int32 ''. en System.RuntimeType.TryChangeType (Valor del objeto, Binder Binder, CultureInfo culture, Boolean needsSpecialCast) en System.RuntimeType.CheckValue (Valor del objeto, Binder Binder, CultureInfo culture, BindingFlags invokeAttr) en System.Reflection.MethodBase.CheckArguments (Object [] parámetros, Binder Binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig) en System.Reflection.RuntimeMethodInfo.Invoke (Object obj, BindingFlags invokeAttr, Binder Binder, Object [] parámetros, CultureInfo culture, Boolean skipVisibilityChecks) en System.Reflection.RuntimeMethodInfo. Invoke (Object obj, BindingFlags invokeAttr, Binder Binder, Object [] parámetros, CultureInfo culture) en System.Reflection.RuntimePropertyInfo.SetValue (Object obj, Object value, BindingFlags invokeAttr, Binder Binder, Object [] index, CultureInfo culture) en MS .Internal.Data.PropertyPathWorker.SetValue (Objeto, Valor del objeto) en MS.Internal.Data.ClrBindingWorker.UpdateValue (Valor del objeto) en System.Windows.Data.BindingExpre ssion.UpdateSource (valor del objeto) ''


¿Se establece DataContext ? En su código subyacente, ¿estableció el valor de su TextBlock en "saadsas" (lo único que puedo adivinar), lo que rompió su enlace de datos?


La vinculación de datos requiere que se NotifyPropertyChanged evento NotifyPropertyChanged cuando se actualiza la fuente. En este caso, querría envolver esta llamada de función en un get / set como tal:

public class FileWrapper: System.ComponentModel.INotifyPropertyChanged{ private string m_filename; public string FileExtension{ get{ return GetFileExtension(FileName);} } public string FileName{ get{ return m_filename;} set{ m_filename = value; OnPropertyChanged("FileName"); OnPropertyChanged( "FileExtension"); } public string GetFileExtension( string filename){ //implementation } public event System.ComponentModel.NotifyPropertyChangedEvent PropertyChanged = (a,b)=>{}; protected void OnPropertyChanged(string property){ PropertyChanged( this, new System.ComponentModel.PropertyChangedEventArgs( property )); } }


Ok, parece que esto es un error al ejecutar WPF 4.0, como se puede ver en los comentarios aquí .

Woops, estaba un poco apresurado ... el ejemplo funciona perfectamente siempre que lo compile para el framework 3.5 (en VS 2010). Pero si lo convierte a proyecto WPF 4.0, el método WeightOnPlanet en ObjectDataProvider no se invoca en el odp2 cuando edita el cuadro de texto. He intentado encontrar nuevos atributos en el Binding o en ObjectDataProvider, pero nada ha funcionado hasta ahora ...

Al compilar en 3.5, funciona bien aquí.



Si bien es posible usar Binding para llamar a un método y obtener su valor de retorno, no es sencillo. Es mucho más sencillo vincular las propiedades y usar la combinación de enlace y notificación de cambio para obtener el resultado que está buscando.

Crea una clase con dos propiedades, Filename y Extension . Filename es solo una propiedad de cadena de lectura / escritura. Extension es una propiedad de cadena de solo lectura cuyo captador llama al método al que está intentando llamar.

Ahora haga que esa clase implemente INotifyPropertyChanged , porque si una propiedad puede cambiar en el código, necesita una forma de decirle al enlace que lo ha hecho. Haga que el colocador de la propiedad Filename de Filename notifique los enlaces que la propiedad de Extension ha cambiado.

Agregue un Binding a un TextBox que se una a la propiedad Filename utilizando el modo TwoWay . Agregue un Binding a un TextBox que se une a la Extension utilizando el modo OneWay predeterminado.

La secuencia de eventos es:

  1. El usuario escribe un nuevo Filename en un TextBox encuadernado y presiona TAB.
  2. El TextBox pierde el foco.
  3. Debido a que el modo de Binding es TwoWay , y está usando el comportamiento predeterminado de actualizar la fuente cuando el objetivo pierde el foco, eso es lo que hace.
  4. El Binding actualiza la fuente llamando al establecedor de Filename .
  5. El definidor de Filename aumenta PropertyChanged .
  6. La Binding maneja PropertyChanged , mira su argumento y ve que la propiedad Extension ha cambiado.
  7. El Binding llama al getter de la propiedad Extension .
  8. El getter de la propiedad Extension llama al método para determinar la extensión de Filename y la devuelve al Binding .
  9. El Binding actualiza su TextBox destino con el nuevo valor de Extension .

Este es el concepto central subyacente al enlace de datos y el patrón MVVM. Una vez que lo entiendes, se convierte en una segunda naturaleza, y el desarrollo de WPF se vuelve aproximadamente diez millones de veces más fácil.