2009-11-17 16 views
7

Ho recentemente ignorato la griglia WPF di DevXpress per dotarmi di una proprietà SelectedObject a cui posso accedere dal mio ViewModel associato in modo approssimativo.Proprietà WPF ReadOnly dependance utilizzando MVVM

Ho creato una proprietà di dipendenza SelectedObject e ho associato OneWayToSource nel mio XAML.

Tutto funziona, ma se provo a renderlo ReadOnly (per completezza) viene visualizzato un errore di compilazione e viene indicato che non è possibile eseguire il binding a una proprietà ReadOnly. Il codice sotto compila, ho incluso (ma rimosso) i bit che ho cercato nei miei tentativi di ottenere la proprietà ReadOnly.

Qualcuno può aiutare per favore?

la proprietà di dipendenza dal mio controllo sovrascritto assomiglia:

//public static readonly DependencyPropertyKey SelectedRowKey = DependencyProperty.RegisterReadOnly("SelectedObject", typeof(object), typeof(MyGrid), new PropertyMetadata(null)); 
//public static readonly DependencyProperty SelectedObjectProperty = SelectedRowKey.DependencyProperty; 

public readonly static DependencyProperty SelectedObjectProperty = DependencyProperty.Register("SelectedObject", typeof(object), typeof(MyGrid), new PropertyMetadata(null)); 

public object SelectedObject 
{ 
    get 
    { 

     return GetValue(SelectedObjectProperty); 
    } 
    set 
    { 
     throw new NotImplementedException(); 
    } 
} 

Il XAML è:

<StackPanel> 
    <devxgrid:MyGrid AutoPopulateColumns="True" DataSource="{Binding Animals}" SelectedObject="{Binding MyObject, Mode=OneWayToSource}" Width="300" Height="300"> 
    <devxgrid:MyGrid.View> 
     <MyGrid:TableView AllowEditing="False" Name="GridView" AutoWidth="True" /> 
    </devxgrid:MyGrid.View> 
</devxgrid:MyGrid> 
</StackPanel> 

risposta

4

Si sta cercando di impostare la proprietà SelectedObject in XAML. Se è di sola lettura, come si può impostare?

Modifica: mi dispiace, mio ​​male. Ho appena capito cosa stai cercando di fare, e hai ragione che dovrebbe funzionare. Tuttavia, WPF non supporta questo scenario, almeno nel 3.5.

Modifica 2: appena verificato .NET 4 e stessa storia.

A proposito, se si è bloccati con DP di sola lettura di qualcun altro che si sta tentando di "spingere" in una VM, è possibile utilizzare un comportamento collegato per risolvere il problema. Ad esempio, si supponga di volere che la VM sia a conoscenza delle proprietà ActualWidth e ActualHeight della propria vista. Puoi scrivere un SizeWatcherBehavior che si collega allo FrameworkElement e ascolta le modifiche alle dimensioni. Quando rilevato, tali modifiche dimensioni sono spinti a leggere/scrivere proprietà associate che il VM può legarsi a:

<Grid local:SizeWatcherBehavior.Watch="True" 
    local:SizeWatcherBehavior.Width="{Binding WidthOnVM, Mode=OneWayToSource}" 
    local:SizeWatcherBehavior.Height="{Binding HeightOnVM, Mode=OneWayToSource}"/> 
+0

Grazie per il vostro aiuto Kent - sfortunatamente non penso di poter usare l'osservatore in nessun DP da usare, ma è bello sapere che cose del genere esistono! Il mio programma funziona comunque, odio solo abbandonare quel "lancio di NotImplementedException();" - Non è una "finestra rotta" ma non è lontana! ma grazie mille per esserti interessato. –

+2

Penso che questo sia un problema serio con WPF e l'adozione del pattern MVVM. Quando la proprietà source è di sola lettura, è possibile definire binding OneWay, il che è ottimo. Ma quando il DP di destinazione è di sola lettura non è possibile definire i binding OneWayToSource. Non capisco perché no ... – Oskar

+0

E sono davvero frustrato nel sentire che anche questo non verrà supportato in .NET 4. – Oskar

0

Stiamo sviluppando una libreria di controllo personalizzato, e uno dei nostri utenti hanno depositato una richiesta di funzionalità per convertire uno dei nostri I DP da Sola lettura a Lettura-Scrittura, poiché ha riscontrato lo stesso problema riscontrato, non possono vincolare OneWayToSource in uno scenario MVVM.

Ovviamente non abbiamo fatto quel DP in lettura e scrittura.

L'utilizzo di proprietà/comportamenti associati per tali scenari è un enorme sovraccarico. La soluzione più semplice sarebbe quella di gestire l'evento "SelectedObjectChanged" nel codice sottostante e impostare la proprietà che si desidera associare a "SelectedObject" DP nel codice sottostante.

A nostro parere, questo approccio "gestisce l'evento e il codice di chiamata da VM/DataContext direttamente" non interrompe MVVM in alcun modo, dal momento che ViewModel non sa ancora nulla della Vista.

+0

Forzare le persone a scrivere codice dietro interrompe in modo istruttivo mvvm. – DanH

4

Sono un po 'in ritardo a questa domanda considerando che è stato chiesto circa 2 anni fa :)

ho fatto una soluzione per essere in modo dinamico in grado di spingere di sola lettura di dipendenza proprietà alla sorgente denominata PushBinding che ho blogged about here .Nel tuo caso sarebbe simile a questa

<devxgrid:MyGrid AutoPopulateColumns="True" 
       DataSource="{Binding Animals}" 
       Width="300" 
       Height="300"> 
    <pb:PushBindingManager.PushBindings> 
     <pb:PushBinding TargetProperty="SelectedObject" Path="MyObject"/> 
    </pb:PushBindingManager.PushBindings> 
    <!--...--> 
</devxgrid:MyGrid> 

PushBinding opere utilizzando due proprietà di dipendenza, ascoltatore e Mirror. L'ascoltatore è associato a OneWay nella TargetProperty e nello PropertyChangedCallback aggiorna la proprietà Mirror che è associata a OneWayToSource a qualsiasi cosa specificata nel Binding.

Demo Project can be Downloaded Here.
Contiene codice sorgente e breve utilizzo del campione oppure visita my WPF blog se sei interessato ai dettagli dell'implementazione.