title: [WPF] DataGrid con ComboBox

text:
Ciao a tutti,
dopo aver googlato invano per due giorni in cerca di una soluzione, vi
pongo il mio problema attuale:
ho una finestra di popup che contiene una datagrid da popolare con
colonne di numero variabile, per cui chi conosce il componente in
questione sa che, a meno di magheggi più o meno complessi, le colonne
vanno aggiunte nel code behind perché non si possono bindare in scrittura.
Detto questo, usando delle colonne con combobox (DataGridComboBoxColumn)
non riesco ad agganciare la selezione con l'aggiornamento della property
bindata del viewmodel:
[lato xaml]:
     <Popup x:Name="EmulatorPopup">
         <DataGrid
		x:Name="BackendEmulatorDatagrid"
		AutoGenerateColumns="False"
		ItemsSource="{Binding EmulationRows}">
         </DataGrid>
     </Popup>
[lato viewmodel]:
     public class BackendEmulatorViewModel : INotifyPropertyChanged
     {
         public event PropertyChangedEventHandler PropertyChanged;
         private void OnPropertyChanged(string propertyName)
         {
             if (PropertyChanged != null)
                 PropertyChanged(this, new
PropertyChangedEventArgs(propertyName));
         }
         private ObservableCollection<EmulationRow> _emulationRows;
         public ObservableCollection<EmulationRow> EmulationRows
         {
             get
             {
                 return _emulationRows;
             }
             set
             {
                 if (_emulationRows != value)
                 {
                     _emulationRows = value;
                     OnPropertyChanged("EmulationRows");
                 }
             }
         }
         private List<EmulationColumn> _socketList;
         public List<EmulationColumn> SocketList
         {
             get
             {
                 return _socketList;
             }
             set
             {
                 if (_socketList != value)
                 {
                     _socketList = value;
                     OnPropertyChanged("SocketList");
                 }
             }
         }
         private static List<string> _sendSockets;
         private static List<string> _receiveSockets;
         public BackendEmulatorViewModel(List<string> sendSockets,
List<string> receiveSockets)
         {
             _sendSockets = sendSockets;
             _receiveSockets = receiveSockets;
             _emulationRows = new ObservableCollection<EmulationRow>();
             _socketList = new List<EmulationColumn>();
             foreach (string s in _sendSockets)
             {
                 _socketList.Add(new EmulationColumn() { Header = s,
SocketDirection = Direction.Send });
             }
             foreach (string r in _receiveSockets)
             {
                 _socketList.Add(new EmulationColumn() { Header = r,
SocketDirection = Direction.Receive });
             }
             foreach (EmulationColumn ec in _socketList)
             {
                 ec.AvailableValues = new List<string>();

ec.AvailableValues.Add(ResponseEditorStrings.BackendEmulatorUndefinedLabel);
                 if (ec.SocketDirection == Direction.Send)
                 {

ec.AvailableValues.Add(ResponseEditorStrings.BackendEmulatorElseLabel);

ec.AvailableValues.Add(ResponseEditorStrings.BackendEmulatorUnmatchedLabel);
                 }
             }
         }
         public enum Direction { Send, Receive };
         public class EmulationColumn : INotifyPropertyChanged
         {
             public event PropertyChangedEventHandler PropertyChanged;
             private void OnPropertyChanged(string propertyName)
             {
                 if (PropertyChanged != null)
                     PropertyChanged(this, new
PropertyChangedEventArgs(propertyName));
             }
             public Direction SocketDirection { get; set; }
             public string Header { get; set; }
             public List<string> AvailableValues { get; set; }
             private string _selectedValue;
             public string SelectedValue
             {
                 get
                 {
                     return _selectedValue;
                 }
                 set
                 {
                     _selectedValue = value;
                     OnPropertyChanged("SelectedValue");
                 }
             }
         }
         public class EmulationRow : INotifyPropertyChanged
         {
             public event PropertyChangedEventHandler PropertyChanged;
             private void OnPropertyChanged(string propertyName)
             {
                 if (PropertyChanged != null)
                     PropertyChanged(this, new
PropertyChangedEventArgs(propertyName));
             }
             private List<string> _cellValues;
             public List<string> CellValues
             {
                 get { return _cellValues; }
                 set
                 {
                     _cellValues = value;
                     OnPropertyChanged("CellValues");
                 }
             }
         }
     }
[lato code behind]:
         public BackendEmulationEditor()
         {
             InitializeComponent();
             EmulatorPopup.Opened += new EventHandler(EmulatorPopup_Opened);
         }
         void EmulatorPopup_Opened(object sender, EventArgs e)
         {
             //la costruzione manuale delle colonne è dovuta al fatto
che DataGrid.Columns non è bindabile
             var bevm = (sender as FrameworkElement).DataContext as
BackendEmulatorViewModel;
             if (bevm != null)
             {
                 BackendEmulatorDatagrid.Columns.Clear();
                 foreach
(SpeechVillage.SpeechDraw.ResponseEditor.ViewModels.BackendEmulatorViewModel.EmulationColumn
ec in bevm.SocketList)
                 {
                     DataGridComboBoxColumn dgcbc = new
DataGridComboBoxColumn()
                     {
                         Header = ec.Header,
                         ItemsSource = ec.AvailableValues,
                         SelectedItemBinding = new Binding("SelectedValue")
//altro tentativo:
//SelectedValueBinding = new Binding("SelectedValue"),
                         //SelectedValuePath = ec.SelectedValue,
                         //DisplayMemberPath = ec.SelectedValue
                     };
                     BackendEmulatorDatagrid.Columns.Add(dgcbc);
                 }
             }
         }
(ho seguito questo link:
http://blogs.msdn.com/b/vinsibal/archive/2008/10/31/wpf-datagrid-datagridcomboboxcolumn-v1-intro.aspx
)
purtroppo la selezione delle combobox non passa per il set di
SelectedValue, da cui capisco che il binding non va a buon fine.
La cosa strana è che non funziona neanche la solution scaricata dal sito
di cui sopra, per cui non capisco cosa c'è che non va, anche se credo
che la chiave del problema sia nella connessione tra combobox e property
(non) bindata.
C'è qualcuno che può aiutarmi? Grazie


title: [WPF] DataGrid con ComboBox

author: marcosabba

text:
Il 08/06/2011 15:12, marcosabba ha scritto:
Aggiungo un'informazione:
se inserisco un converter vuoto:
         void EmulatorPopup_Opened(object sender, EventArgs e)
         {
             //la costruzione manuale delle colonne è dovuta al fatto
che DataGrid.Columns non è bindabile
             var bevm = (sender as FrameworkElement).DataContext as
BackendEmulatorViewModel;
             if (bevm != null)
             {
                 BackendEmulatorDatagrid.Columns.Clear();
                 foreach
(SpeechVillage.SpeechDraw.ResponseEditor.ViewModels.BackendEmulatorViewModel.EmulationColumn
ec in bevm.SocketList)
                 {
                     Binding binding = new Binding("SelectedValue");
                     binding.Converter = new EmptyConverter();
                     DataGridComboBoxColumn dgcbc = new
DataGridComboBoxColumn()
                     {
                         Header = ec.Header,
                         ItemsSource = ec.AvailableValues,
                         SelectedItemBinding = binding,
                         //SelectedValueBinding = binding,
                         //SelectedValuePath = ec.SelectedValue,
                         //DisplayMemberPath = ec.SelectedValue
                     };
                     BackendEmulatorDatagrid.Columns.Add(dgcbc);
                 }
                 BackendEmulatorDatagrid.CanUserSortColumns = false;
                 BackendEmulatorDatagrid.ItemsSource = bevm.EmulationRows;
             }
         }
noto che il binding con la property SelectedValue in qualche modo è
avvenuto, passa per la ConvertBack del converter e mostra come valore la
stringa selezionata nella combobox. Poi però l'assegnamento del valore
alla property non va a buon fine (eccezione NullReferenceException con
questa StackTrace:
    at
System.Windows.Data.BindingExpression.IsValidValueForUpdate(Object
value, Type sourceType)
    at System.Windows.Data.BindingExpression.ConvertProposedValue(Object
value)
    at
System.Windows.Data.BindingExpression.ValidateAndConvertProposedValue(Collection`1&
values)
    at
System.Windows.Controls.DataGridHelper.ValidateWithoutUpdate(FrameworkElement
element)
    at
System.Windows.Controls.DataGridColumn.CommitCellEdit(FrameworkElement
editingElement)
    at
System.Windows.Controls.DataGridColumn.CommitEdit(FrameworkElement
editingElement)
    at System.Windows.Controls.DataGridCell.CommitEdit()
    at
System.Windows.Controls.DataGrid.OnExecutedCommitEdit(ExecutedRoutedEventArgs
e)
    at System.Windows.Controls.DataGrid.OnExecutedCommitEdit(Object
sender, ExecutedRoutedEventArgs e)
    at System.Windows.Input.CommandBinding.OnExecuted(Object sender,
ExecutedRoutedEventArgs e)
    at System.Windows.Input.CommandManager.ExecuteCommandBinding(Object
sender, ExecutedRoutedEventArgs e, CommandBinding commandBinding)
    at
System.Windows.Input.CommandManager.FindCommandBinding(CommandBindingCollection
commandBindings, Object sender, RoutedEventArgs e, ICommand command,
Boolean execute)
    at System.Windows.Input.CommandManager.FindCommandBinding(Object
sender, RoutedEventArgs e, ICommand command, Boolean execute)
    at System.Windows.Input.CommandManager.OnExecuted(Object sender,
ExecutedRoutedEventArgs e)
    at System.Windows.UIElement.OnExecutedThunk(Object sender,
ExecutedRoutedEventArgs e)
    at
System.Windows.Input.ExecutedRoutedEventArgs.InvokeEventHandler(Delegate
genericHandler, Object target)
    at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler,
Object target)
    at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object
target, RoutedEventArgs routedEventArgs)
    at System.Windows.EventRoute.InvokeHandlersImpl(Object source,
RoutedEventArgs args, Boolean reRaised)
    at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender,
RoutedEventArgs args)
    at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean
trusted)
    at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter,
IInputElement target, Boolean userInitiated)
    at System.Windows.Input.RoutedCommand.Execute(Object parameter,
IInputElement target)
    at System.Windows.Controls.DataGrid.EndEdit(RoutedCommand command,
DataGridCell cellContainer, DataGridEditingUnit editingUnit, Boolean
exitEditMode)
    at System.Windows.Controls.DataGrid.CommitAnyEdit()
    at System.Windows.Controls.DataGrid.OnEnterKeyDown(KeyEventArgs e)
    at System.Windows.Controls.DataGrid.OnKeyDown(KeyEventArgs e)
    at System.Windows.UIElement.OnKeyDownThunk(Object sender,
KeyEventArgs e)
    at System.Windows.Input.KeyEventArgs.InvokeEventHandler(Delegate
genericHandler, Object genericTarget)
    at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler,
Object target)
    at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object
target, RoutedEventArgs routedEventArgs)
    at System.Windows.EventRoute.InvokeHandlersImpl(Object source,
RoutedEventArgs args, Boolean reRaised)
    at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender,
RoutedEventArgs args)
    at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
    at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean
trusted)
    at System.Windows.Input.InputManager.ProcessStagingArea()
    at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
    at System.Windows.Input.InputProviderSite.ReportInput(InputReport
inputReport)
    at
System.Windows.Interop.HwndKeyboardInputProvider.ReportInput(IntPtr
hwnd, InputMode mode, Int32 timestamp, RawKeyboardActions actions, Int32
scanCode, Boolean isExtendedKey, Boolean isSystemKey, Int32 virtualKey)
    at
System.Windows.Interop.HwndKeyboardInputProvider.ProcessKeyAction(MSG&
msg, Boolean& handled)
    at
System.Windows.Interop.HwndSource.CriticalTranslateAccelerator(MSG& msg,
ModifierKeys modifiers)
    at System.Windows.Interop.HwndSource.OnPreprocessMessage(Object param)
    at
System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate
callback, Object args, Int32 numArgs)
    at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object
source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
    at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority
priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
    at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority
priority, Delegate method, Object arg)
    at System.Windows.Interop.HwndSource.OnPreprocessMessageThunk(MSG&
msg, Boolean& handled)
    at
System.Windows.Interop.HwndSource.WeakEventPreprocessMessage.OnPreprocessMessage(MSG&
msg, Boolean& handled)
    at System.Windows.Interop.ThreadMessageEventHandler.Invoke(MSG& msg,
Boolean& handled)
    at
System.Windows.Interop.ComponentDispatcherThread.RaiseThreadMessage(MSG&
msg)
    at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame
frame)
    at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
    at System.Windows.Threading.Dispatcher.Run()
    at System.Windows.Application.RunDispatcher(Object ignore)
    at System.Windows.Application.RunInternal(Window window)
    at System.Windows.Application.Run(Window window)
    at System.Windows.Application.Run()
    at SpeechVillage.SpeechDraw.SpeechDraw.Main() in
D:\Documenti\SpeechVillageProjects\Visual Studio
2010\Projects\SD3\src\XXXXXX\obj\x86\Debug\XXXXXX.g.cs:line 50
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly,
String[] args)
    at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence
assemblySecurity, String[] args)
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
    at System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state, Boolean
ignoreSyncCtx)
    at System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
    at System.Threading.ThreadHelper.ThreadStart()
)


title: [WPF] DataGrid con ComboBox

author: Mauro Servienti [MVP]

text:
Ciao marcosabba,

io non ho capito :-)
puoi dettagliare meglio come gira il fumo nello xaml?
.m
--
Mauro Servienti
{C67C0157-5D98-4733-A75E-93CAEE4BADC8}
Microsoft MVP - Visual C# / MCTS
http://mvp.support.microsoft.com/profile/mauro
blog @
http://milestone.topics.it
whynot [ at ] topics [ dot ] it


title: [WPF] DataGrid con ComboBox

text:
Il 08/06/2011 18:38, Mauro Servienti [MVP] ha scritto:
> io non ho capito :-)
> puoi dettagliare meglio come gira il fumo nello xaml?
Ciao Mauro, intanto grazie.
Chiedo scusa in anticipo se il post è "lungo" ma inserisco più dettagli
possibile.
Lato xaml c'è ben poca roba, visto che il tutto lo butto dentro lato
code behind. In soldoni,
[lato xaml]:
      <Popup x:Name="EmulatorPopup">
          <DataGrid
         x:Name="BackendEmulatorDatagrid"
         AutoGenerateColumns="False">
          </DataGrid>
      </Popup>
[lato code behind del popup]:
public partial class BackendEmulationEditor : UserControl
{
     public BackendEmulationEditor()
     {
         InitializeComponent();
         EmulatorPopup.Opened += new EventHandler(EmulatorPopup_Opened);
     }
     void EmulatorPopup_Opened(object sender, EventArgs e)
     {
         //la costruzione manuale delle colonne è dovuta al fatto che
DataGrid.Columns non è bindabile
         var bevm = (sender as FrameworkElement).DataContext as
BackendEmulatorViewModel;
         if (bevm != null)
         {
             BackendEmulatorDatagrid.Columns.Clear();
             foreach
(XXXX.YYYY.ResponseEditor.ViewModels.BackendEmulatorViewModel.EmulationColumn
ec in bevm.SocketList)
             {
                 Binding binding = new Binding("SelectedVal");
                 binding.Converter = new EmptyConverter();
                 DataGridComboBoxColumn dgcbc = new
DataGridComboBoxColumn()
                 {
                     Header = ec.Header,
                     ItemsSource = ec.AvailableValues,
                     //SelectedItemBinding = binding,
                     SelectedValuePath = ec.SelectedVal,
                     SelectedValueBinding = binding,
                     //DisplayMemberPath = ec.SelectedValue
                 };
                 BackendEmulatorDatagrid.Columns.Add(dgcbc);
             }
             BackendEmulatorDatagrid.CanUserSortColumns = false;
             BackendEmulatorDatagrid.ItemsSource = bevm.EmulationRows;
         }
     }
}
i settaggi sul componente DataGrid come vedi li faccio tramite
BackendEmulatorDatagrid sul gestore dell'evento Opened, lì imposto
l'ItemsSource della DataGrid, cioè la collection delle righe. Il view
model te lo riscrivo qui sotto:











         private string _selectedVal;
         public string SelectedVal
         {
             get
             {
                 return _selectedVal;
             }
             set
             {
                 _selectedVal = value;
                 OnPropertyChanged("SelectedVal");
             }
         }
     }
     public class EmulationRow : INotifyPropertyChanged
     {
         public event PropertyChangedEventHandler PropertyChanged;
         private void OnPropertyChanged(string propertyName)
         {
             if (PropertyChanged != null)
                 PropertyChanged(this, new
PropertyChangedEventArgs(propertyName));
         }
         private List<string> _cellValues;
         public List<string> CellValues
         {
             get { return _cellValues; }
             set
             {
                 _cellValues = value;
                 OnPropertyChanged("CellValues");
             }
         }
     }
}
L'ultimo dettaglio che manca è come apro da un menù la popup:
[...]
                     BackendEmulatorViewModel bevm = new
BackendEmulatorViewModel(new List<string>() { "send1","send2" }, new
List<string>() { "receive1", "receive2" }); //per i test, da sostituire
con valori attuali
                     //Posiziono il popup sotto il treeview item
relativo all'azione attuale (usa un'extension method)
                     revm.BackendEmulationEditor.DataContext = bevm;
                     Popup backendEmulationEditorWindow =
revm.BackendEmulationEditor.EmulatorPopup;
                     var item = ((revm.View as
IResponseEditorView).TreeViewEditorView.tvParameters).ContainerFromItem(this)
as TreeViewItem;
                     backendEmulationEditorWindow.PlacementTarget = item;
                     backendEmulationEditorWindow.Placement =
PlacementMode.Bottom;
                     backendEmulationEditorWindow.IsOpen = true; //qui
si apre la popup
                     backendEmulationEditorWindow.StaysOpen = true;
Per chiarire cosa funziona e cosa no:
mettendo un break sulle righe return di questo converter:
     public class EmptyConverter : IValueConverter
     {
         public object Convert(object value, Type targetType, object
parameter, CultureInfo culture)
         {
             return value;
         }
         public object ConvertBack(object value, Type targetType, object
parameter, CultureInfo culture)
         {
             return value;
         }
     }
e sulle get e set della property SelectedVal, il debugger si ferma sulla
get di SelectedVal in apertura ma non sul return di Convert, poi quando
scelgo un valore nelle combobox (correttamente riempite) e premo enter,
il debugger si ferma sul ConvertBack ma non sul set di SelectedVal.
Cioè, il binding funziona? Si e no! Non capisco davvero, e tutto ciò è
frustrante, non riesco a trovare qualcuno che in rete abbia avuto un
problema simile, forse cerco male o forse non ho capito un tubazzo...
ciao


title: [WPF] DataGrid con ComboBox

text:
Aggiornamento:
il problema non sta nella DataGridComboBoxColumn, il binding non va a
buon fine neanche con una DataGridTextColumn:
//DataGridComboBoxColumn dgcbc = new DataGridComboBoxColumn()
DataGridTextColumn dgcbc = new DataGridTextColumn()
{
	Header = ec.Header,
	//ItemsSource = ec.AvailableValues,
	//SelectedItemBinding = binding,
	//SelectedValuePath = ec.SelectedVal,
	//SelectedValueBinding = binding,
	//DisplayMemberPath = ec.SelectedValue
	Binding = binding
};
comincio a pensare che il modo con cui apro la Popup window non sia
ortodosso... in pratica il componente che contiene la Popup (che
contiene la DataGrid) è istanziato a priori, contenuto nel componente
padre, e viene aperto alla bisogna.
Quello che faccio prima di aprire è creare un viewmodel apposito e
cambiare al popup il datacontext sotto al ... sedere.
ripeto:
                     BackendEmulatorViewModel bevm = new
BackendEmulatorViewModel(new List<string>() { "send1","send2" }, new
List<string>() { "receive1", "receive2" }); //per i test, da sostituire
con valori attuali
                     //Posiziono il popup sotto il treeview item
relativo all'azione attuale (usa un'extension method)
                     revm.BackendEmulationEditor.DataContext = bevm;
                     Popup backendEmulationEditorWindow =
revm.BackendEmulationEditor.EmulatorPopup;
                     var item = ((revm.View as
IResponseEditorView).TreeViewEditorView.tvParameters).ContainerFromItem(this)
as TreeViewItem;
                     backendEmulationEditorWindow.PlacementTarget = item;
                     backendEmulationEditorWindow.Placement =
PlacementMode.Bottom;
                     backendEmulationEditorWindow.IsOpen = true; //qui
si apre la popup
continuo a indagare e vi tengo agiornati, scusate il "rumore di fondo"
ma può darsi che tutto ciò serva a qualcun altro, dunque vado avanti


title: [WPF] DataGrid con ComboBox

text:
Ciao marcosabba,
You wrote on 09/06/2011 :
> comincio a pensare che il modo con cui apro la Popup window non sia
> ortodosso... in pratica il componente che contiene la Popup (che contiene la
> DataGrid) è istanziato a priori, contenuto nel componente padre, e viene
> aperto alla bisogna.
ma... il DataContext è definto a livello di?
Perchè il controllo Popup ha un po' di caratteristiche speciali nella
gestione del DataBinding perchè a tutti gli effetti quello che finisce
dentro il popup è in una *window* *diversa* da quella dove sei tu.



title: [WPF] DataGrid con ComboBox

text:
Il 09/06/2011 19:18, Mauro Servienti [MVP] ha scritto:
> ma... il DataContext è definto a livello di?
> Perchè il controllo Popup ha un po' di caratteristiche speciali nella
> gestione del DataBinding perchè a tutti gli effetti quello che finisce
> dentro il popup è in una *window* *diversa* da quella dove sei tu.
ho visto che in effetti c'era un problema di datacontext, perché
succedeva una cosa strana facendo così (BackendEmulationEditor è il mio
componente popup con datagrid inclusa):
revm.BackendEmulationEditor = new UI.BackendEmulationEditor();
revm.BackendEmulationEditor.DataContext = bevm; //bevm è il viewmodel
in pratica pensavo che questo datacontext fosse ereditato da Popup e
Datagrid, invece datagrid ereditava il datacontext del componente da cui
chiamavo popup.IsOpen = true (ma perché !?!?)
dunque, dopo aver forzato il datacontext così:
revm.BackendEmulationEditor.BackendEmulatorDatagrid.DataContext = bevm;
revm.BackendEmulationEditor.EmulatorPopup.DataContext = bevm;
pensavo di aver risolto, invece no, perché dopo aver sistemato un
problema sul db di una solution di esempio che avevo scaricato, ho visto
che se si imposta un ItemsSource sul datagrid, i binding dichiarati
nelle colonne hanno come datacontext la classe che rappresenta le righe:
Binding binding = new Binding("SelectedVal");
binding.Converter = new EmptyConverter();
DataGridTextColumn dgcbc = new DataGridTextColumn()
{
	Header = ec.Header,
	Binding = binding
};
BackendEmulatorDatagrid.Columns.Add(dgcbc);
SelectedVal nel mio caso deve stare su EmulationRow...
Dunque in conclusione ho capito che:
1) invece di fare tentativi a vanvera dovevo studiare di più il
componente _prima_ di usarlo
2) la datagrid è pensata per strutture con colonne note a priori, perché
la classe che rappresenta la riga deve sapere a quali campi riferire le
properties a cui bindare i valori delle celle
3) forse la datagrid non va bene nel mio caso in cui avrei bisogno di
una matrice meno "db" oriented, oppure devo lanciarmi in "magheggi" poco
ortodossi (poco ortodossi è un modo per dire che io non sono capace di
capirli e gestirli...)
4) forse ho sbagliato mestiere (ho questi momenti di frustrazione
softwaristica, abbiate pazienza ;)


title: Silverlight BusyIndicator

author: Smalville

text:
Ciao,
è possibile "disabiltare" l'utilizzo di una pagina mentre il
busyindicatore ha la proprietà IsBusy=true?
Vorrei evitare che gli utenti continuino a premere sui pulsanti
rilanciando le operazione se il BusyIndicator indica che già
un'operazione è in corso.
Grazie mille
Ciao :)


title: Garbage collector: quando interviene?

author: Midnightmare

text:
[Cross post su it.comp.dotnet e it.comp.java]
Salve,
ho scritto in C++ un algoritmo che costruisce un albero, se non si verifica
una certa condizione lo distrugge, e ne ricostruisce uno più grande.
Il tutto ripetuto finché non si verifica un'altra condizione.
Utilizzando il distruttore e delete riesco a deallocare tutta la memoria
prima che parta la costruzione del nuovo albero.
Ma in C# e Java, dovendomi affidare alla gestione automatica della memoria
che cosa accadrebbe? So che posso invocare il GC manualmente, ma chi mi
garantisce che agisca subito sull'albero?
Considerando che la radice iniziale è sempre la stessa (è lo stesso nodo),
magari man mano che il nuovo albero viene costruito, il GC dealloca i nodi
del vecchio?
E se il nuovo albero venisse costruito partendo da una radice diversa dalla
precedente, in quale momento il GC deallocherebbe l'albero vecchio?
L'albero può occupare anche oltre un gigabyte.
Grazie


title: Garbage collector: quando interviene?

author: Raffaele Rialdi [MVP]

text:

Quanto scrivo vale solo per dotnet.
Il criterio generale per tutti i GC è che loro riescono a gestire le
allocazioni/deallocazioni in modo più efficiente di quanto  puoi fare
tu.
Se fai un ciclo di allocazioni/disallocazioni in raw win32 scoprirai
che le allocazioni hanno un costo alto, costo che il GC cerca di
minimizzare con un altra fondamentale ottimizzazione: Il CLR cerca di
mantenere tutto ciò che è in generazione 0 e 1 dentro la cache L2,
rendendo ancora più performante l'esecuzione del tuo codice.
Per capire a fondo il meccanismo ci vorrebbe mezza giornata di talk con
una serie di esempi che mi sono preparato nel tempo.
Per farla corta il GC è giustamente non-deterministico perché lui può
decidere in modo più efficiente.
Il principio su cui si basa il GC del CLR è che le allocazioni fatte
più di recente saranno in tutta probabilità quelle disallocate prima.
In pratica il GC alloca degli ephemeral segment (pezzi di memoria di
lunghezza fissa, al momento di 16MB) all'interno dei quali viene
spostato un puntatore per allocare memoria. La collection serve a
'deframmentare' i buchi lasciati da disallocazioni 'random'.
Detto questo, il tuo algoritmo fa esattamente ciò che si aspetta il GC.
E se tu ad ogni loop disallochi tutto, la disallocazione non sarà altro
che spostare il puntatore indietro mantenendo in memoria il "costoso"
segmento di 16MB (fino a quando il GC non decide che conviene
rilasciarlo, decisione che dipende da una serie di fattori che
tralascio).
Se invece hai una singola allocazione superiore a circa 85K (cifra su
cui non ti devi fossilizzare e passiva di cambiamenti in future
versioni) va direttamente in LOH (Large Object Heap) che sta in
Generazione 2 e non è soggetta a 'deframmentazione' durante la
collection.
Questo significa che:
- se le tue allocazioni sono grosse, fatti un pool di memoria per tutto
il loop e poi rilascia.
- se le tue allocazioni sono piccole, non abbondare mai in dimensioni
di allocazione (come si faceva in C/C++) perché migliori le performance
se sta tutto in L2
Ci sarebbe molto altro da dire ma l'unica cosa saggia da fare è di
misurare e vedere tu stesso quali sono le condizioni migliori
(ovviamente devi fare cicli molto lunghi per avere risultati
accettabili)
Buon lavoro
--
Raffaele Rialdi
http://www.iamraf.net
Weblog:
http://blogs.ugidotnet.org/raffaele
Microsoft MVP profile
https://mvp.support.microsoft.com/profile/raffaele
UGIdotNET -
http://www.ugidotnet.org/


title: Garbage collector: quando interviene?

text:
"Raffaele Rialdi [MVP]" <
malta@n0spam_vevy.com
> ha scritto:
> Quanto scrivo vale solo per dotnet.
[CUT]
Grazie per la risposta.
Cosa intendi di preciso con Generazione 0, 1, 2 etc..?


title: Garbage collector: quando interviene?

text:
Midnightmare wrote:
> Grazie per la risposta.
Prego
>
> Cosa intendi di preciso con Generazione 0, 1, 2 etc..?
È il modo in cui funziona il GC del framework. C'è un'ottima
spiegazione sul libro di Richter (CLR via C#).
In due parole le allocazioni più giovani stanno in gen0 man mano che
passa tempo e restano in memoria passano in gen1 e infine in gen2.
Queste tre generazioni sono soggette alla garbage collection
('deframmentazione' + disallocazione) mentre la speciale LOH non è
soggetta a collection.



title: Garbage collector: quando interviene?

text:
"Raffaele Rialdi [MVP]" <
malta@n0spam_vevy.com
> ha scritto:
> In due parole le allocazioni piï¿œ giovani stanno in gen0 man mano che passa
> tempo e restano in memoria passano in gen1 e infine in gen2.
Allora l'avevo intuito :D


title: Garbage collector: quando interviene?

author: rootkit

text:
On 9 Gen, 09:51, "Midnightmare" <
midnightmareNOS...@live.it
> wrote:
> Ma in C# e Java, dovendomi affidare alla gestione automatica della memoria
> che cosa accadrebbe? So che posso invocare il GC manualmente, ma chi mi
> garantisce che agisca subito sull'albero?
parlando di java e della implementazione hotspot: nel momento in cui
l'albero viene dereferenziato viene candidato per il gc, per il tuo
applicativo l'heap torna libera e virtualmente pronta per la nuova
allocazione senza bisogno ne di aspettare il passaggio del gc ne di
invocarlo manualmente.
il grosso problema di fare questi continui cicli di allocazione sono
le performance. il modello gc della hotspot è organizzato in modo
generazionale proprio per ridurre l'area di memoria su cui
intervenire, da una parte la cosiddetta "young generation" dove
vengono creati i nuovi oggetti e dall'altra la "tenured generation"
dove vengono via via spostati gli oggetti "sopravvissuti" (poi ci
sarebbe la "perm generation" ma questa è un'altra storia). ad ogni
passaggio il gc dealloca la memoria degli oggetti candidati nell'eden
e sposta i sopravvissuti verso la generazione successiva, liberando
quindi spazio per i nuovi oggetti. in automatico interviene solo
quando c'è bisogno, cioè quando c'è carenza di spazio nell'eden,
perché su heap di gigabytes il passaggio del gc costa caro in termini
di tempo cpu. il problema è che facendo cicli continui di allocazione/
deallocazione di giga di oggetti tu poni sempre le condizioni per cui
il gc deve intervenire e ogni volta spazza a tappeto tutto l'eden.
ciò premesso, arrivo alle conclusioni:
- chiamare il gc manualmente non guadagni nulla in termini di utilizzo
di memoria mentre ci smeni in termini di ottimizzazione di utilizzo.
in altre parole il gc sa da se quando deve intervenire ed è meglio
fidarsi
- se devi allocare e deallocare giga di oggetti è molto meglio se
predisponi una cache permanente.
- dietro al tuning del gc c'è un mondo, vale la pena di documentarsi
se si hanno a cuore le performaces.


title: Garbage collector: quando interviene?

text:
"rootkit" <
root...@gmail.com
> ha scritto:
> ciň premesso, arrivo alle conclusioni:
> - chiamare il gc manualmente non guadagni nulla in termini di utilizzo
> di memoria mentre ci smeni in termini di ottimizzazione di utilizzo.
Ma i tempi sono equivalenti a quelli che si avrebbero deallocando
manualmente in C++?
> - se devi allocare e deallocare giga di oggetti č molto meglio se
> predisponi una cache permanente.
Allocare all'inizio e deallocare alla chiusura del programma?


title: Garbage collector: quando interviene?

text:
On 10 Gen, 16:14, "Midnightmare" <
midnightmareNOS...@live.it
> wrote:
> > ci premesso, arrivo alle conclusioni:
> > - chiamare il gc manualmente non guadagni nulla in termini di utilizzo
> > di memoria mentre ci smeni in termini di ottimizzazione di utilizzo.
>
> Ma i tempi sono equivalenti a quelli che si avrebbero deallocando
> manualmente in C++?
non proprio. è (anche) per questo che prevale la logica "dealloco solo
quando è necessario", logica che può sembrare sprecona ma in realtà fa
risparmiare tanti cicli cpu.
> > - se devi allocare e deallocare giga di oggetti molto meglio se
> > predisponi una cache permanente.
>
> Allocare all'inizio e deallocare alla chiusura del programma?
usare un pool di oggetti preallocati invece di riallocarli ogni volta.
naturalmente la butto lì e non so se sia applicabile nel tuo caso.


title: Garbage collector: quando interviene?

text:
rootkit wrote:
>> Ma i tempi sono equivalenti a quelli che si avrebbero deallocando
>> manualmente in C++?
>
> non proprio. ï¿œ (anche) per questo che prevale la logica "dealloco solo
> quando ï¿œ necessario", logica che puï¿œ sembrare sprecona ma in realtï¿œ fa
> risparmiare tanti cicli cpu.
quoto, in molti casi le perf con il GC sono superiori. Ovviamente
possiamo trovare molti casi in cui sono peggiori (dipendono dal
contesto). IL GC ï¿œ una soluzione generica e come tale ha dei
compromessi ma d'altro canto ti elimina un sacco di grattacapi e quindi
ï¿œ quella piï¿œ papabile.
BTW i Garbage Collector sono un concetto molto piï¿œ vecchio di
java/.net, nati per risolvere problemi in C++. Chi scrive giochi sa
bene che un giocatore accanito puï¿œ arrivare ad avere dei out of memory
in C++ anche se non ci sono leak, ma solo perchï¿œ la memoria ï¿œ
frammentata (ovviamente parlo di sistemi a 32 bit). I GC minimizzano
questo specifico problema.
>>> - se devi allocare e deallocare giga di oggetti molto meglio se
>>> predisponi una cache permanente.
>>
>> Allocare all'inizio e deallocare alla chiusura del programma?
>
> usare un pool di oggetti preallocati invece di riallocarli ogni volta.
> naturalmente la butto lï¿œ e non so se sia applicabile nel tuo caso.
Per quanto riguarda .net, la preallocazione ï¿œ preferibile solo se le
singole allocazioni vanno in LOH (>85K). Per vedere se vanno in LOH la
cosa piï¿œ facile ï¿œ usare perfmon e visualizzare il grafico delle varie
generazioni.
Diversamente si ottengono generalmente prestazioni migliori lasciando
fare tutto al GC.
Come valutarlo? Misurando il tuo contesto specifico.



title: Garbage collector: quando interviene?

text:
"rootkit" <
root...@gmail.com
> ha scritto:
> usare un pool di oggetti preallocati invece di riallocarli ogni volta.
> naturalmente la butto lě e non so se sia applicabile nel tuo caso.
Si tratta di un algoritmo che calcola tutti i percorsi (minimi) per
raggiungere da un punto A, un punto B all'interno di un labirinto.
Ho scritto due versioni ed una tiene in memoria l'albero precedente e usa le
foglie come radici dei sotto alberi che poi saranno creati, costruendo un
albero piů grande. Il programma risulta essere sensibilmente piů veloce
rispetto a quello che distrugge e ricrea continuamente, ma tenere in memoria
tutte quelle foglie fa consumare molta piů memoria.


title: Garbage collector: quando interviene?

text:
"Raffaele Rialdi [MVP]" <
malta@n0spam_vevy.com
> ha scritto:
> Per quanto riguarda .net, la preallocazione è preferibile solo se le
> singole allocazioni vanno in LOH (>85K). Per vedere se vanno in LOH la
> cosa più facile è usare perfmon e visualizzare il grafico delle varie
> generazioni.
Ma per valutare le dimensioni di una singola allocazione non basta una
sizeof dell'oggetto che viene allocato?


title: Garbage collector: quando interviene?

text:
Midnightmare wrote:
> Ma per valutare le dimensioni di una singola allocazione non basta una sizeof
> dell'oggetto che viene allocato?
Non ti conviene farlo dinamicamente.
La strategia migliore è quella di predisporre un pool di blob per
quelle allocazioni che sono decisamente più grosse di circa 85K.
Il pool può essere una lista/dictionary/set/... di blocchi di memoria
che riutilizzi ad ogni giro. A te sta l'onere di cancellarlo (se serve)
e di aggiungere nuove allocazioni qualora sia necessario.
Alla fine butti via tutto e il numero di allocazioni/disallocazioni
sarà inferiore con conseguente miglioramento delle prestazioni (che
devi misurare per vedere se ha senso nel tuo caso).
Tieni conto che se i blocchi sono grossi e finiscono in LOH, non sono
comunque soggetti al passo di 'deframmentazione' del GC che è il passo
più oneroso del GC (finalizzazione a parte che non dovrebbe avere luogo
nel tuo caso).



title: Garbage collector: quando interviene?

text:
Midnightmare wrote:
> Si tratta di un algoritmo che calcola tutti i percorsi (minimi) per
> raggiungere da un punto A, un punto B all'interno di un labirinto.
Per curiosità cosa usi, Dijkstra, Floyd-Warshall (pesato) o cosa?



title: Garbage collector: quando interviene?

text:
"Raffaele Rialdi [MVP]" <
malta@n0spam_vevy.com
> ha scritto:
> Per curiosità cosa usi, Dijkstra, Floyd-Warshall (pesato) o cosa?
No. Praticamente è un algoritmo che avevo scritto per cercare tutte le
occorrenze di una parola all'interno di una matrice, tenendo conto del fatto
che le lettere fossero adiacenti (in una delle 8 circostanti insomma) e che
non fossero usate più di una volta. Poi su un forum lessi di un utente
appassionato di intelligenza artificiale, che aveva sviluppato un algoritmo
per i labirinti e mi sono accorto che il mio poteva essere applicato a quel
caso, poiché un percorso del labirinto si può rappresentare anche come una
stringa del tipo P[spazio][spazio][spazio]...[spazio]A dove P e A sono i
punti di partenza e arrivo.
Sicuramente sarà ottimizzabile, ma confrontandolo con l'algoritmo scritto da
quell'utente, i miei (quello veloce e quello che consuma meno memoria) sono
molto più veloci e trovano tutte le soluzioni minime. Solo che ovviamente
per labirinti molto grandi nascono problemi relativi all'uso della memoria.
Magari la soluzione sarebbe utilizzare uno degli algoritmo da te citati, ma
mi chiedo se con quelli la soluzione trovata è solo una o se si trovano
tutte.


title: Garbage collector: quando interviene?

text:

Non discuto sulla bontà del codice che hai scritto ma gli algoritmi che
ho citato hanno alle spalle una soluzione matematica che garantisce di
trovare il percorso minimo in differenti condizioni. Guarda anche
quello di Kruskal.
Eulero a parte, gli algoritmi di ottimizzazione moderni sono nati
durante la guerra e successivamente utilizzati nel campo
commerciale/finanziario.
Quello che un dev può fare non è altro che la ricerca alla migliore
implementazione di un modello matematico che difficilmente può essere
superato.
Personalmente ti consiglio di dare un'occhiata almeno a quei due
algoritmi (Dijkstra probabilmente è il più semplice per il tuo caso) e
vedere quanto differisce la performance.
Per trovare tutte le possibili soluzioni ti dovrebbe bastare cambiare
opportunamente i costi associati agli archi.



title: Garbage collector: quando interviene?

text:
"Raffaele Rialdi [MVP]" <
malta@n0spam_vevy.com
> ha scritto:
> Quello che un dev può fare non è altro che la ricerca alla migliore
> implementazione di un modello matematico che difficilmente può essere
> superato.
Su questo sono d'accordo.
> Personalmente ti consiglio di dare un'occhiata almeno a quei due algoritmi
> (Dijkstra probabilmente è il più semplice per il tuo caso) e vedere quanto
> differisce la performance.
> Per trovare tutte le possibili soluzioni ti dovrebbe bastare cambiare
> opportunamente i costi associati agli archi.
Questi algoritmi agiscono su grafi già costruiti in cui i costi degli archi
sono differenti.
L'algoritmo che ho scritto io analizza la matrice e crea un albero in cui la
distanza massima tra la radice e una foglia è la distanza minima tra i due
punti. Inoltre un eventuale grafo in cui ogni nodo rappresenterebbe una
cella della matrice, avrebbe tutti i costi degli archi uguali a 1 e questo
forse creerebbe qualche problema nella ricerca di tutte le soluzione.
Su wikipedia leggo che: l'algoritmo di Floyd-Warshall calcola lo shortest
path per tutte le coppie di un grafo pesato.
A me servirebbero tutti gli shortest path per ogni coppia.
Ma aggiungo anche che non conoscendo bene l'argomento (praticamente ho letto
qualcosa solo su quello di Dijkstra), probabilmente ho una visione limitata
delle applicazioni di tali algoritmi ad un caso come il mio.
Direi che siamo OT, anche se questi argomenti nel mondo della
programmazione, in fondo sono sempre IT :D


title: Garbage collector: quando interviene?

text:
"Midnightmare" <
midnightm...@live.it
> ha scritto:
> Su wikipedia leggo che: l'algoritmo di Floyd-Warshall calcola lo shortest
> path per tutte le coppie di un grafo pesato.
> A me servirebbero tutti gli shortest path per ogni coppia.
Volevo dire per una coppia (a scelta).


title: Garbage collector: quando interviene?

text:
Midnightmare wrote:
> Questi algoritmi agiscono su grafi già costruiti in cui i costi degli archi
> sono differenti.
> L'algoritmo che ho scritto io analizza la matrice e crea un albero in cui la
> distanza massima tra la radice e una foglia è la distanza minima tra i due
> punti. Inoltre un eventuale grafo in cui ogni nodo rappresenterebbe una cella
> della matrice, avrebbe tutti i costi degli archi uguali a 1 e questo forse
> creerebbe qualche problema nella ricerca di tutte le soluzione.
> Su wikipedia leggo che: l'algoritmo di Floyd-Warshall calcola lo shortest
> path per tutte le coppie di un grafo pesato.
> A me servirebbero tutti gli shortest path per ogni coppia.
> Ma aggiungo anche che non conoscendo bene l'argomento (praticamente ho letto
> qualcosa solo su quello di Dijkstra), probabilmente ho una visione limitata
> delle applicazioni di tali algoritmi ad un caso come il mio.
>
> Direi che siamo OT, anche se questi argomenti nel mondo della programmazione,
> in fondo sono sempre IT :D
La modifica per trovare tutti le possibili soluzioni non dovrebbe
essere complicata. Qui trovi un po' di idee:
http://stackoverflow.com/questions/2819347/dijkstras-algorithm-to-find-all-the-shortest-paths-possible
In particolare guarda questo link:
http://www.ics.uci.edu/~eppstein/pubs/Epp-SJC-98.pdf



title: Garbage collector: quando interviene?

text:
"Raffaele Rialdi [MVP]" <
malta@n0spam_vevy.com
> ha scritto:
> La modifica per trovare tutti le possibili soluzioni non dovrebbe essere
> complicata. Qui trovi un po' di idee:
>
http://stackoverflow.com/questions/2819347/dijkstras-algorithm-to-find-all-the-shortest-paths-possible
> In particolare guarda questo link:
>
http://www.ics.uci.edu/~eppstein/pubs/Epp-SJC-98.pdf
Un bel documento sull'argomento.
Grazie


title: [WPF] Refresh combobox forzato non funziona

text:
Ciao a tutti.
Ho questa situazione:
Lato DataContext:
         private List<string> _fieldList;
         public List<string> FieldList
         {
             get
             {
                 _fieldList.Clear();
                 FillFieldList();
                 return _fieldList;
             }
             set
             {
                 _fieldList = value;
                 OnPropertyChanged("FieldList");
             }
         }
[...]
         private void FillFieldList()
         {
             _fieldList.Add("Previous block");
             foreach (IBlock b in this.Scope.BlockSet)
             {
                 _fieldList.Add(b.Name);
             }
         }
e una combobox che gli si "binda":
     <ControlTemplate x:Key="ComboBoxContentControl" >
         <ComboBox
             x:Name="FieldComboBox"
             Margin="1"
             Padding="1"
             Background="{x:Null}"
             ItemsSource="{Binding Path=FieldList, Mode=OneWay}"
             SelectionChanged="selectionChangedHandler"
             ButtonBase.Click="cbButtonClicked"
             SelectedIndex="{Binding Path=SelectedIndex, Mode=OneTime}">
         </ComboBox>
     </ControlTemplate>
con "cbButtonClicked" voglio forzare una rilettura del Source del
binding, perché alcune operazioni in altri componenti possono modificare
la condizione su Scope.BlockSet(vedi sopra).
A tale scopo:
         void cbButtonClicked(object sender, RoutedEventArgs e)
         {
             ComboBox cb = sender as ComboBox;
             if (cb != null)
             {
                 BindingExpression be =
cb.GetBindingExpression(ComboBox.ItemsSourceProperty);
                 be.UpdateTarget();
             }
         }
Ciò mi scatena correttamente la rilettura del get di FieldList, che
viene correttamente aggiornata (per esempio, passa da 2 a 3 elementi) ma
la combobox, quando si apre, mostra sempre i 2 elementi precedenti.
Cos'è che non riesco a vedere? Non vorrei farvi perdere tempo, e ho
l'impressione che sia una boiata, ma a quest'ora e con due sole ore di
sonno alle spalle, sono decisamente in panne...


text:
Ciao marcosabba,
You wrote on 24/05/2011 :
> Ciò mi scatena correttamente la rilettura del get di FieldList, che viene
> correttamente aggiornata (per esempio, passa da 2 a 3 elementi) ma la
> combobox, quando si apre, mostra sempre i 2 elementi precedenti.
> Cos'è che non riesco a vedere? Non vorrei farvi perdere tempo, e ho
> l'impressione che sia una boiata, ma a quest'ora e con due sole ore di sonno
> alle spalle, sono decisamente in panne...
a naso mi viene da pensare che il motore di data binding sia smart e si
accorda che la reference non è cambiata ergo ignora la cosa, del resto
la "list" è sempre quella. Se così fosse mi viene una domanda: ma
perchè quel codice così farraginoso? se usassi una
ObservableCollection<String> avresti tutto gratis al volo, inoltre
perchè esposse il "setter" della list come pubblico?
.m
--
Mauro Servienti
{C67C0157-5D98-4733-A75E-93CAEE4BADC8}
Microsoft MVP - Visual C# / MCTS
http://mvp.support.microsoft.com/profile/mauro
blog @
http://milestone.topics.it
whynot [ at ] topics [ dot ] it


text:
Il 24/05/2011 21:49, Mauro Servienti [MVP] ha scritto:
> a naso mi viene da pensare che il motore di data binding sia smart e si
> accorda che la reference non è cambiata ergo ignora la cosa, del resto
> la "list" è sempre quella. Se così fosse mi viene una domanda: ma perchè
> quel codice così farraginoso? se usassi una ObservableCollection<String>
> avresti tutto gratis al volo, inoltre perchè esposse il "setter" della
> list come pubblico?
Sei meglio di Wolf in Pulp Fiction...
così va meglio:
         private ObservableCollection<string> _fieldList;
         public ObservableCollection<string> FieldList
         {
             get
             {
                 _fieldList.Clear();
                 FillFieldList();
                 return _fieldList;
             }
         }
il setter non serviva proprio (e giulio da tempo cerca invano di levarmi
il vizio di mettere il setter pubblico "a prescindere") ma onestamente
non capisco il perché di quel comportamento precedente, o meglio, credo
di capire che dichiarare la privata _fieldList come ObservableCollection
mi dà la notifica propertychanged già inclusa (e mi sembra anche la
collectionchanged, o sbaglio?) dunque quando agisco "privatamente"
facendo add, clear, e quant'altro ho tutta una serie di notifiche che
col caso precedente non avevo.
Comunque, grazie 1000


text:
marcosabba wrote:
> il setter non serviva proprio (e giulio da tempo cerca invano di levarmi il
> vizio di mettere il setter pubblico "a prescindere") ma onestamente non
> capisco il perché di quel comportamento precedente, o meglio, credo di capire
> che dichiarare la privata _fieldList come ObservableCollection mi dà la
> notifica propertychanged già inclusa (e mi sembra anche la collectionchanged,
> o sbaglio?) dunque quando agisco "privatamente" facendo add, clear, e
> quant'altro ho tutta una serie di notifiche che col caso precedente non
> avevo.
La notifypropertychanged no e se la vuoi devi sempre spararla tu quando
rimpiazzi il reference della collection.
Le notifiche interne alla collection (add, remove, insert) invece le
spara la observablecollection.
Se la tua collection è immutabile, la observable non ti serve a nulla.
Se l'istanza della tua collection è sempre la stessa per tutta la
durata del VM, la notifypropertychanged non ti serve a nulla.
--
Raffaele Rialdi
http://www.iamraf.net
Weblog:
http://blogs.ugidotnet.org/raffaele
Microsoft MVP profile
https://mvp.support.microsoft.com/profile/raffaele
UGIdotNET -
http://www.ugidotnet.org/


text:
Ciao marcosabba,
You wrote on 25/05/2011 :
> Sei meglio di Wolf in Pulp Fiction...
:-)
> ma onestamente non capisco il perché di quel comportamento precedente
il motore di data binding fa questo ragionamento: tu gli dai una
reference, poi gli dici di fare l'update, ma lui dice la reference non
è cabiata perchè mai devo sprecare tempo a fare l'update? lui non ha la
più pallida idea che la reference internamente sia diversa, l'unica
cosa che può fare è un ReferenceEquals con quello che ha in mano.



text:
Il 25/05/2011 10:42, Raffaele Rialdi [MVP] ha scritto:
> La notifypropertychanged no e se la vuoi devi sempre spararla tu quando
> rimpiazzi il reference della collection.
ah, allora ricordavo male, pensavo che per esempio facendo una
myObservableCollection = new ObservableCollection<string>()
partisse la propertychanged. Ok.
> Le notifiche interne alla collection (add, remove, insert) invece le
> spara la observablecollection.
ok questo lo ricordavo, la collectionchanged mi sembra
> Se la tua collection è immutabile, la observable non ti serve a nulla.
> Se l'istanza della tua collection è sempre la stessa per tutta la durata
> del VM, la notifypropertychanged non ti serve a nulla.
il caso è infatti questo, lavoro sulla stessa collection che viene
svuotata/riempita alla bisogna, quello che ancora non mi è chiaro
(nonostante adesso con la observablecollection funzioni) è perché la
combobox, opportunamente "titillata" con
cb.GetBindingExpression(ComboBox.ItemsSourceProperty).UpdateTarget();
faceva riscattare il get della property bindata, aggiornava il numero di
items ma non aggiornava il numero degli elementi visuali.
Forse come diceva Mauro quando il binding è su una property "normale"
(List) c'è un accoppiamento "smart" che non vedendo cambio di reference
non aggiorna il componente, e forse dotando la property di un gestore
della collectionchanged la cosa poteva funzionare. Per ora sono
soddisfatto così, poi se ho cinque minuti faccio la prova.
Grazie


text:
marcosabba wrote:
> ah, allora ricordavo male, pensavo che per esempio facendo una
> myObservableCollection = new ObservableCollection<string>()
> partisse la propertychanged. Ok.
Nessuna magia :) Se sostituisci un reference, non c'è meccanismo
(almeno per ora) che ti permetta di far scattare un evento (e meno male
perché il costo in performance c'è e non è proprio poco).
> il caso è infatti questo, lavoro sulla stessa collection che viene
> svuotata/riempita alla bisogna, quello che ancora non mi è chiaro (nonostante
> adesso con la observablecollection funzioni) è perché la combobox,
> opportunamente "titillata" con
> cb.GetBindingExpression(ComboBox.ItemsSourceProperty).UpdateTarget();
> faceva riscattare il get della property bindata, aggiornava il numero di
> items ma non aggiornava il numero degli elementi visuali.
Mai avuto problemi del genere, ... è da chiarire. Ovviamente fa molta
differenza anche il Mode del binding a seconda se sei mono o
bidirezionale (e la cosa cambia a seconda di come è stata dichiarata la
DP) ma per un caso semplice come itemssource non vedo proprio problemi.
> Forse come diceva Mauro quando il binding è su una property "normale" (List)
> c'è un accoppiamento "smart" che non vedendo cambio di reference non aggiorna
> il componente, e forse dotando la property di un gestore della
> collectionchanged la cosa poteva funzionare. Per ora sono soddisfatto così,
> poi se ho cinque minuti faccio la prova.
ok, ma in ogni caso non ci sono magie. Ci vuole un evento che notifichi
alla view di aggiornare gli item



title: Unire piu' classi

author: BlackSun

text:
Ciao,
----------------------------------------------
Visual Basic Express 2008
S.O.: Win XP
----------------------------------------------
una domanda molto banale sulle classi. Come posso creare una classe
che contenga tutte le proprieta' di 4 classi diverse?
Es:
- Classe A contiene 5 proprieta'
- Classe B contiene 4 proprieta'
- Classe C contiene 3 proprieta'
- Classe D contiene 3 proprieta'
io vorrei avere una classe E che in qualche modo possa contenerle
tutte e 15 (senza doverla creare ad hoc).
Grazie mille
Ciao Blacksun


title: Unire piu' classi

text:

Ereditarietà?
class E : A, B, C, D
Al3x


title: Unire piu' classi

text:
Ciao,
che io sappia VB nn supporta la multi ereditarieta'. Ogni classe puo'
avere solo una classe padre.
O sbaglio?
Ciao BlackSun



title: Unire piu' classi

text:
On 25 Mag, 11:43, BlackSun <
black_...@email.it
> wrote:
> Ciao,
> che io sappia VB nn supporta la multi ereditarieta'. Ogni classe puo'
> avere solo una classe padre.
> O sbaglio?
Non sbagli mi sono confuso io (lavoro più che altro con C# dove NON è
supportata e ricordavo che VB la supportasse ma mi confondevo con C+
+!).
Direi che l'unica maniera è quella di implementare un po' di
interfacce...
http://msdn.microsoft.com/it-it/library/28e2e18x(v=VS.90).aspx
Una cosa del tipo (se la sinstassi qui sotto è mista VB / C#
perdonami :-) )
interface iA
{
 prop 1;
 prop 2;
}
interface iB
{
 prop 3;
prop 4;
}
...
class A : iA
class B : iB
...
classe E : iA, iB, iC, ...
Che dici: può funzionare?
Al3x


title: Unire piu' classi

text:
On May 25, 10:53 am, BlackSun <
black_...@email.it
> wrote:
> Ciao,
> ----------------------------------------------
> Visual Basic Express 2008
> S.O.: Win XP
> ----------------------------------------------
>
> una domanda molto banale sulle classi. Come posso creare una classe
> che contenga tutte le proprieta' di 4 classi diverse?
Come già detto non è disponibile l'ereditarietà multipla di classi. O
erediti multiple interfacce, oppure aggreghi nella classe "E" le
altre, cioé esponi classi A, B, C, D come proprietà della classe E.
mt


title: Unire piu' classi

author: dedalus

text:
On 25/05/2011 10:53, BlackSun wrote:
> io vorrei avere una classe E che in qualche modo possa contenerle
> tutte e 15 (senza doverla creare ad hoc).
Non è buona norma ereditare solo perchè si vuole avere una
"funzionalità" che esiste in un'altra classe (ossia, banalmente, si
vuole scrivere meno codice): se erediti la classe ereditata deve essere
un sottotipo altrimenti non erediti, perchè la tua astrazione sarebbe
difficilmente uniforme (e mi sembrerebbe strano che una classe sia
contemporaneamente un sottotipo di 5 altre classi).
Questo in generale, nel particolare .Net non supporta l'ereditarietà
multipla.
Se il tuo problema è quello di scrivere meno codice perchè sei pigro
(... come tutti ;-) ), la soluzione della delega (che ti hanno già
proposto) è quella migliore.
Se invece, il tuo è un vero problema di astrazione e quello che insegui
è un comportamento polimorfico, allora la soluzione delle interfacce
(già suggerita anche questa) è quella migliore.
Ciao.


title: Unire piu' classi

text:
Ciao,
> > io vorrei avere una classe E che in qualche modo possa contenerle
> > tutte e 15 (senza doverla creare ad hoc).
>
> Non è buona norma ereditare solo perchè si vuole avere una
> "funzionalità" che esiste in un'altra classe (ossia, banalmente, si
> vuole scrivere meno codice): se erediti la classe ereditata deve essere
> un sottotipo altrimenti non erediti, perchè la tua astrazione sarebbe
> difficilmente uniforme (e mi sembrerebbe strano che una classe sia
> contemporaneamente un sottotipo di 5 altre classi).
Non e' per scrivere meno codice, mi basterebbe fare copia e incolla
delle proprieta' di tutte le classi e crearne una ad hoc, ma volevo
evitare di (in futuro) dover ricordarmi di modificare _entrambi_ le
classi riducendo la possiblita' di errore. E' per questo che pensavo
ad una classe padre che raccogliesse le altre, so che e' una forzatura
visto che le 4 classi non hanno nulla in comune se non un indice.
> Se il tuo problema è quello di scrivere meno codice perchè sei pigro
> (... come tutti ;-) ), la soluzione della delega (che ti hanno già
> proposto) è quella migliore.
>
> Se invece, il tuo è un vero problema di astrazione e quello che insegui
> è un comportamento polimorfico, allora la soluzione delle interfacce
> (già suggerita anche questa) è quella migliore.
Come ti dicevo il problema e' solo quello... evitare dimenticanze nel
caso ad una classe aggiunga una proprieta'.
Bah... ci faccio una pensata... valuto anche (se me lo passano)
l'eventualita' di cambiare l'acquisizione dei dati.
Grazie :-)
Ciao BlackSun


title: Unire piu' classi

text:
BlackSun wrote:
> Non e' per scrivere meno codice, mi basterebbe fare copia e incolla
> delle proprieta' di tutte le classi e crearne una ad hoc, ma volevo
> evitare di (in futuro) dover ricordarmi di modificare _entrambi_ le
> classi riducendo la possiblita' di errore. E' per questo che pensavo
> ad una classe padre che raccogliesse le altre, so che e' una forzatura
> visto che le 4 classi non hanno nulla in comune se non un indice.
Probabilmente c'è da chiedersi prima se veramente ha senso, dal punto
di vista di modellazione, avere 5 classi di cui una che comprenda le
proprietà di tutte le altre 4.
Non lo sto escludendo a priori, nè sto criticando, dico solo che
meriterebbe un'analisi più approfondita.
Se l'analisi rivela che è necessario, puoi sempre avvalerti di
generatori di codice (T4 template tanto per dire una possibilità) che
ti eviti l'onere della manutenzione.
--
Raffaele Rialdi
http://www.iamraf.net
Weblog:
http://blogs.ugidotnet.org/raffaele
Microsoft MVP profile
https://mvp.support.microsoft.com/profile/raffaele
UGIdotNET -
http://www.ugidotnet.org/


title: Unire piu' classi

text:
Ciao,
> Probabilmente c'è da chiedersi prima se veramente ha senso, dal punto
> di vista di modellazione, avere 5 classi di cui una che comprenda le
> proprietà di tutte le altre 4.
No, non ha senso avere la 5^ classe.
Il fatto e' che bisognerebbe rifare totalmente l'acquisizione dei dati
e questo significherebbe rifare il lavoro (e non vogliono)... in
pratica e' una bella toppona, con due P :-)
> Non lo sto escludendo a priori, nè sto criticando, dico solo che
> meriterebbe un'analisi più approfondita.
Come sopra... l'analisi imporebbe il rifacimento del lavoro ma per
vari motivi non e' stato passato.
> Se l'analisi rivela che è necessario, puoi sempre avvalerti di
> generatori di codice (T4 template tanto per dire una possibilità) che
> ti eviti l'onere della manutenzione.
T4 template? Vado a vederlo....
Grazie.
Ciao BlackSun


title: [EF] Entity Framework utilizza dei proxy?

author: Giulio Petrucci

text:
Ciao a tutti,
premesso che la mia esperienza nel mondo degli ORM inizia meno di un
anno fa e che mi sono limitato a NHibernate, volevo chiedervi: quando
con EF faccio una "Get" su un certo oggetto di tipo A con una property
di tipo B, la property in questione è valorizzata mediante un proxy?
Ciao e grazie,
Giulio
--


title: dispose di una window wpf

author: Sander

text:
ho una piccola applicazione che apre una window (new e showdialog()),
la window apre una pagina web in un webbrowser, legge dei valori e li
pone in una List<>, esce con un Close().
Ripete questa cosa anche per centinaia di volte .
Ad ogni nuova apertura della window, vedo che una decina di MB vengono
scalati dalla memoria disponibile del sistema, tanto che lasciandola
andare credo che vada in crash in qualche ora e comunque non è bello
tutto cio :)
Forse sbaglio qualche concetto che entra in gioco in questi casi, pero
da quello che ho letto, una Close() è sufficiente a fare il Dispose
della window.
Domande per chi le sa:
1 Perche la memoria continua inesorabilmente a diminuire anche se la
window viene soggetta a Close? Non c'e nulla che io stia accumulando
come dati,trascrivo solo in un DB.
2 Se la window viene effettivamente 'Disposed' , come mai invece è
disponibile qulasiasi sua variabile pubblica anche dopo la chiusura?
Grazie molte,
Sandro


title: dispose di una window wpf

text:

Nei controlli WPF non hai più la dispose perché non sono wrapper di una
risorsa nativa.
A quanto ho capito facendo dei test, il dispatcher di WPF si occupa di
disallocare le risorse grafiche non appena queste non vengono più
utilizzate. Questa è una mia deduzione che non ho mai trovato in alcuna
documentazione ma che ho riscontrato dopo i test che ho descritto in
questo mio post:
http://blogs.ugidotnet.org/raffaele/archive/2009/02/20/wpf-elaborazioni-lunghe-e-presunti-memory-leak.aspx
Se effettivamente stai riscontrando un leak le possibilità sono:
1. stai ricadendo nel caso che ho descritto in quel post e non stai
lasciando che il dispatcher abbia il tempo di rilasciare le risorse
grafiche.
2. le tue window in realtà sono ancora referenziate in modo diretto o
indiretto (per esempio con un event handler) e quindi non possono
essere buttate via nè dal GC nè dal dispatcher di wpf.
Il primo caso, una volta capito, è facile da sistemare secondo quanto
ho scritto nel post.
Il secondo caso è facilmente diagnosticabile usando un profiler di
memoria (
vs.net
, ants di red gate, etc.)
--
Raffaele Rialdi
http://www.iamraf.net
Weblog:
http://blogs.ugidotnet.org/raffaele
Microsoft MVP profile
https://mvp.support.microsoft.com/profile/raffaele
UGIdotNET -
http://www.ugidotnet.org/


title: dispose di una window wpf

text:

Non mi cambia, neanche col Dispatcher.Invoke del tuo interessante
articolo......ho tolto anche qualsiasi referenza alle window , che
comunque erano soltanto riguardanti letture di variabili una volta
closed. A me questo webbrowser non mi suona...tra l'altro sono arrivato
a questa piccola architettura (main window e window in showdialog)
perche un unico webbrowser sulla stessa main window, prima o poi si
'incollava' e non caricava la nuova pagina. In questo modo almeno ogni
volta si 'rinnova'.  Ma temo fortemente che ne rimanga qualche pezzetto
in giro.


title: dispose di una window wpf

text:
Sander wrote:
> Non mi cambia, neanche col Dispatcher.Invoke del tuo interessante
> articolo......ho tolto anche qualsiasi referenza alle window , che comunque
> erano soltanto riguardanti letture di variabili una volta closed. A me questo
> webbrowser non mi suona...tra l'altro sono arrivato a questa piccola
> architettura (main window e window in showdialog) perche un unico webbrowser
> sulla stessa main window, prima o poi si 'incollava' e non caricava la nuova
> pagina. In questo modo almeno ogni volta si 'rinnova'.  Ma temo fortemente
> che ne rimanga qualche pezzetto in giro.
Tutto quanto dicevo prima sul discorso Dispose non vale per il
controllo webbrowser che usa IE in interop e quindi (come avrai già
visto) ha il metodo Dispose che deve essere chiamato.
Non so bene come stai facendo ma sull'evento/command di Close della
Window che contiene il webbrowser, chiama la dispose del webbrowser
stesso.
Per curiosità verifica anche se vengono aperti tanti processi
iexplore.exe o no.
Se non riesci a trovare una causa, la strada più veloce è quella di
usare un profiler.



title: dispose di una window wpf

text:
Il 09/06/2011 15:37, Raffaele Rialdi [MVP] ha scritto:
> Sander wrote:
>> Non mi cambia, neanche col Dispatcher.Invoke del tuo interessante
>> articolo......ho tolto anche qualsiasi referenza alle window , che
>> comunque erano soltanto riguardanti letture di variabili una volta
>> closed. A me questo webbrowser non mi suona...tra l'altro sono
>> arrivato a questa piccola architettura (main window e window in
>> showdialog) perche un unico webbrowser sulla stessa main window, prima
>> o poi si 'incollava' e non caricava la nuova pagina. In questo modo
>> almeno ogni volta si 'rinnova'. Ma temo fortemente che ne rimanga
>> qualche pezzetto in giro.
>
> Tutto quanto dicevo prima sul discorso Dispose non vale per il controllo
> webbrowser che usa IE in interop e quindi (come avrai già visto) ha il
> metodo Dispose che deve essere chiamato.
>
> Non so bene come stai facendo ma sull'evento/command di Close della
> Window che contiene il webbrowser, chiama la dispose del webbrowser stesso.
> Per curiosità verifica anche se vengono aperti tanti processi
> iexplore.exe o no.
>
> Se non riesci a trovare una causa, la strada più veloce è quella di
> usare un profiler.
>
No, ho controllato e non vengono aperti processi iexplore aprendo la
window che possiede il webbrowser. E comunque va MOLTO meglio chiamando
la Dispose() del webbrowser in chiusura. Mi perdo ancora qualcosina in
memoria ad ogni chiamata/chiusura, ma è quasi nullo e tra l'altro sembra
che non tutto venga recuperato immediatamente, ma anche avanti nel tempo.
Grazie Raf, per ora va benissimo cosi, ora andrà stressato per vedere
cosa accade su tempi lunghi.
E' da tenere a mente questa cosa del webbrowser....
Sandro


title: dispose di una window wpf

text:
Sander wrote:
> No, ho controllato e non vengono aperti processi iexplore aprendo la window
> che possiede il webbrowser. E comunque va MOLTO meglio chiamando la Dispose()
> del webbrowser in chiusura. Mi perdo ancora qualcosina in memoria ad ogni
> chiamata/chiusura, ma è quasi nullo e tra l'altro sembra che non tutto venga
> recuperato immediatamente, ma anche avanti nel tempo.
>
> Grazie Raf, per ora va benissimo cosi, ora andrà stressato per vedere cosa
> accade su tempi lunghi.
>
> E' da tenere a mente questa cosa del webbrowser....
Se è così, il problema è solo quello.
Le differenze che vedi in memoria sono parte del normale comportamento
del GC che è non-deterministico.
Come regola generale, dove c'è una Dispose è sempre meglio chiamarla
non appena non usi più l'oggetto.
Ciao!



title: Intercettare mouse su child di container

text:
Ciao a tutti, vediamo se sono fortunato :-)
Ho una window con all'interno un container (MDIContainer per essere
preciso) dove all'interno mi si aprono runtime svariati usercontrol
(fondamentalmente altre window sotto forma di user control). La cosa
che vorrei fare è intercettare il mouse (ideale sarebbe il passaggio
sopra ma anche un focus andrebbe bene) quando questo si trova sopra ad
uno dei miei usercontrol... avete idee o esempi?
Ho già giocato parecchio con quello che già avevo "gratis" (come
MouseEnter/MouseLeave della Windows/Container/USerControl, ...) ma non
sono riuscito ad ottenere proprio quello che mi serve ma solo qualcosa
di simile e non funzionanente nel 100% dei casi (*).
Grazie,
Al3x
(*) la migliore soluzione mi porta a capire che il fuoco va sul
containter e che il focus è sul mio usercontrol ma, se esce dallo
usercontrol senza uscire dal container non intercetto nulla...


text:
Ciao Al3xI98O,
non fare xpost tra qui e i forum MS altrimenti ci perdiamo tutti per
strada.
grazie
.m
--
Mauro Servienti
{C67C0157-5D98-4733-A75E-93CAEE4BADC8}
Microsoft MVP - Visual C# / MCTS
http://mvp.support.microsoft.com
blog @
http://milestone.topics.it
whynot [ at ] topics [ dot ] it


text:
On 23 Feb, 13:27, Mauro Servienti [MVP] <mauroservie...@online.nospam>
wrote:
> non fare xpost tra qui e i forum MS altrimenti ci perdiamo tutti per
> strada.
In realtà non pensavo che anche questo fosse "parente" del forum non
essendo un vecchio *.microsoft.* (che so essere in "decadenza")  anche
se vedo che alcuni ci sono sia qui che di la... (ma tanti mi pare che
qui ci siano e di la noo sbaglio?
Al3x


text:
On 23 Feb, 12:44, Al3xI98O <
bon...@gmail.com
> wrote:
Per chi fosse interessato sposto virtualmente il thread qui sul forum
MS di WPF:
http://social.msdn.microsoft.com/Forums/it-IT/wpfit/thread/b23c18e7-76cb-43de-8e71-77b39751baf3
Al3x


author: LudovicoVan

text:

Ne so quanto te del destino prossimo della gerarchia microsoft, ma su
Usenet vale la regola generale che piuttosto che mandare messaggi
gemelli su gruppi diversi e' bene mandare un unico messaggio
contemporaneamente a tutti i gruppi interessati (i gruppi destinatari
di un messaggio possono essere piu' di uno). Ovviamente e' bene
comunque non esagerare ed includere solo i gruppi per i quali il
quesito e' davvero rilevante.
-LV


text:
On Feb 23, 2:37 pm, Al3xI98O <
bon...@gmail.com
> wrote:
> On 23 Feb, 12:44, Al3xI98O <
bon...@gmail.com
> wrote:
>
> Per chi fosse interessato sposto virtualmente il thread qui sul forum
> MS di WPF:
>
>
http://social.msdn.microsoft.com/Forums/it-IT/wpfit/thread/b23c18e7-7.
..
Ne so poco o nulla di WPF (ci ho giusto giocato un po'), per cui non
vale neanche la pena che io intervenga in quel thread (a cui rimando
per una discussione del tuo quesito). D'altra parte, te la butto li',
per quel che puo' valere: forse stai cercando di intercettare eventi
al livello sbagliato, ovvero piuttosto che intercettare eventi al
livello di interfaccia forse dovresti intercettare eventi al livello
di "data-source"...
Ma non mi chiedere altro, tanto non ti saprei rispondere! :)
-LV


text:

Fra l'altro, scusa, mi sono confuso: quella era piuttosto una risposta
per il thread "wpf evento new row sul datagrid"...
-LV


text:
On 23 Feb, 16:45, LudovicoVan <
ju...@diegidio.name
> wrote:
> Fra l'altro, scusa, mi sono confuso: quella era piuttosto una risposta
> per il thread "wpf evento new row sul datagrid"...
Che non è nemmeno mio :-)
Cmq concordo con la tua risposta in questo caso :-)
Al3x


text:
On 23 Feb, 16:25, LudovicoVan <
ju...@diegidio.name
> wrote:
> Ne so quanto te del destino prossimo della gerarchia microsoft, ma su
> Usenet vale la regola generale che piuttosto che mandare messaggi
> gemelli su gruppi diversi e' bene mandare un unico messaggio
> contemporaneamente a tutti i gruppi interessati
Su questo c'è una bella diatriba perchè c'è chi sostiene il
contrario :-)
Io di norma non faccio cross post e tecnicamente non l'ho fatto
nemmeno ora perchè il Forum di cui parla Mauro è appunto un forum e
non un un NG di Usenet :-)
Al3x


text:
Ciao Al3xI98O,
You wrote on 23/02/2011 :
> Io di norma non faccio cross post e tecnicamente non l'ho fatto
> nemmeno ora perchè il Forum di cui parla Mauro è appunto un forum e
> non un un NG di Usenet :-)
questo è vero, solo che io vi accedo via NNTP e non mi ricordo mai di
questa cosa.



text:
On 23 Feb, 16:29, LudovicoVan <
ju...@diegidio.name
> wrote:
> Ne so poco o nulla di WPF (ci ho giusto giocato un po'), per cui non
> vale neanche la pena che io intervenga in quel thread (a cui rimando
> per una discussione del tuo quesito). D'altra parte, te la butto li',
> per quel che puo' valere: forse stai cercando di intercettare eventi
> al livello sbagliato, ovvero piuttosto che intercettare eventi al
> livello di interfaccia forse dovresti intercettare eventi al livello
> di "data-source"...
In realtà sto sperimentando proprio il banale "focus" su di una
finestra senza base dati (o altro di simile).
In teoria ho anche risolto o meglio l'ho fatto funzionare ma fa
piuttosto pena come metodo...
Al3x
PS: la "soluzione" la posto di la per non sovrascrivere le due
cose :-)


title: Come 'parlano' un client ed un server dcom ?

author: RobertoA

text:
Dispongo di un programma gestionale che integra un client dcom (client opc)
per comunicare con un server dcom (server opc) che a sua volta 'parla' con
delle schede elettroniche installate in fabbrica
In sostanza il programma di supervisione e' il client opc, che parla col
server opc, il quale a sua volta sa come dialogare con le schede
elettroniche
Bene, fin qua' niente di anormale, e' l'architettura usata da gran parte
degli scada in commercio per dialogare con plc e sistemi di misura sul
campo, una specie di odbc per i database, uno strato intermedio tra dati e
client
Ora, vorrei realizzare una scheda elettronica che integri al suo interno la
funzionalita' di opc server (che in sostanza e' un dcom server)
Vista la limitatezza di risorse in termini di memoria disponibile a bordo
scheda, vorrei implementare un opc server ridotto all'osso e quindi abile
solo per la lettura dei canali di ingresso della scheda stessa
Supponiamo che non conosca niente della tecnologia Opc
Supponiamo che non conosca niente della tecnologia Dcom
Supponiamo che abbia a disposizione un sistema di test composto da un opc
client, un opc server, una scheda elettronica che risponde all'opc server
Supponiamo che l'opc client sia un programma in esecuzione sul pc1, l'opc
server sia un programma in esecuzione sul pc2, la scheda elettronica abbia
porta ethernet, e tutti e r i dispositivi siano collegati nella stessa rete
locale e dispongano di stack tcp/ip funzionante
La domanda e': come fare per capire cosa avviene nel momento che un opc
client invia una richiesta all'opc server desiderato ed ottiene una
risposta?
In sintesi, vorrei capire come fare per inviare comandi, via lan, dall'opc
client direttamene verso la scheda elettronica ed ottererne delle risposte
Ciao e grazie
RobertoA


text:
RobertoA wrote:
> Vista la limitatezza di risorse in termini di memoria disponibile a bordo
> scheda, vorrei implementare un opc server ridotto all'osso e quindi abile
> solo per la lettura dei canali di ingresso della scheda stessa
> Supponiamo che non conosca niente della tecnologia Opc
> Supponiamo che non conosca niente della tecnologia Dcom
> Supponiamo che abbia a disposizione un sistema di test composto da un opc
> client, un opc server, una scheda elettronica che risponde all'opc server
> Supponiamo che l'opc client sia un programma in esecuzione sul pc1, l'opc
> server sia un programma in esecuzione sul pc2, la scheda elettronica abbia
> porta ethernet, e tutti e r i dispositivi siano collegati nella stessa rete
> locale e dispongano di stack tcp/ip funzionante
> La domanda e': come fare per capire cosa avviene nel momento che un opc
> client invia una richiesta all'opc server desiderato ed ottiene una risposta?
> In sintesi, vorrei capire come fare per inviare comandi, via lan, dall'opc
> client direttamene verso la scheda elettronica ed ottererne delle risposte
> Ciao e grazie
> RobertoA
Stai scegliendo la strada più complicata e che non ti darà risultati.
A livello di rete vedrai solo il traffico tcp/ip generato
dall'infrastruttura RPC usata da DCOM.
Il protocollo RPC è molto complesso e intervenire a questo livello non
è produttivo.
Per scrivere un opc (client o server) devi necessariamente studiare e
comprendere a fondo il suo protocollo. Questo credo che sarà il punto
indispensabile.
Per quanto riguarda dcom probabilmente potrai farne a meno e
incapsulare tutte le richieste di opc dentro, ad esempio, una
comunicazione basata su WCF. Dcom infatti ha numerosi problemi non
semplici da superare tra cui la security.
Se però devi interagire con l'infrastruttura dcom già esistente, non
potrai fare a meno di studiarti come funziona e implementare gli
oggetti con le interfacce richieste dalla tua infrastruttura opc/dcom.
--
Raffaele Rialdi
http://www.iamraf.net
Weblog:
http://blogs.ugidotnet.org/raffaele
Microsoft MVP profile
https://mvp.support.microsoft.com/profile/raffaele
UGIdotNET -
http://www.ugidotnet.org/


text:
"Raffaele Rialdi [MVP]" <
malta@n0spam_vevy.com
> ha scritto nel messaggio
news:mn.53097db70...@n0spamvevy.com...

> Raffaele Rialdi
http://www.iamraf.net
> Weblog:
http://blogs.ugidotnet.org/raffaele
> Microsoft MVP profile
https://mvp.support.microsoft.com/profile/raffaele
> UGIdotNET -
http://www.ugidotnet.org/
Il fatto e' che tutta la documentazione relativa a rpc e dcom viene vista
sempre da dentro un ambiente Microsoft Windows
'trasportare' il tutto (o almeno la parte che mi interessa) su di una
schedina proprietaria mi sembra un'impresa titanica a meno di trovare delle
funzionalita' gia' belle e pronte esattamente per il micro che usero', e su
questo gia' c'ho messo una pietra sopra
Poi, per avere la documentazione adeguata su opc client/server bisogna
'arruolarsi' tra i partner sostenitori di OpcConnect e li vanno fuori
qualche migliaio di euro
Viste le considerazioni sopra e visto che mi basta una funzionalita' base
base (mi basta leggere alcuni di un opc server), pensavo che 'sniffare' la
rete avrebbe potuto farmi vedere cosa passava come richiesta e cosa veniva
restituito come risposta dal sistema di test di cui gia' dispongo
Replicarlo con la scheda elettronica sarebbe poi stata una bella impresa ma
comunque un obiettivo raggiungibile
Ciao e grazie
RobertoA


text:
RobertoA wrote:
> Il fatto e' che tutta la documentazione relativa a rpc e dcom viene vista
> sempre da dentro un ambiente Microsoft Windows
> 'trasportare' il tutto (o almeno la parte che mi interessa) su di una
> schedina proprietaria mi sembra un'impresa titanica a meno di trovare delle
> funzionalita' gia' belle e pronte esattamente per il micro che usero', e su
> questo gia' c'ho messo una pietra sopra
> Poi, per avere la documentazione adeguata su opc client/server bisogna
> 'arruolarsi' tra i partner sostenitori di OpcConnect e li vanno fuori qualche
> migliaio di euro
Guarda se questo link ti puï¿œ essere utile:
http://www.opcconnect.com/source.php
> Viste le considerazioni sopra e visto che mi basta una funzionalita' base
> base (mi basta leggere alcuni di un opc server), pensavo che 'sniffare' la
> rete avrebbe potuto farmi vedere cosa passava come richiesta e cosa veniva
> restituito come risposta dal sistema di test di cui gia' dispongo
> Replicarlo con la scheda elettronica sarebbe poi stata una bella impresa ma
> comunque un obiettivo raggiungibile
Il traffico rpc ï¿œ piuttosto complesso. Adesso ci sono le specs
pubblicate da Microsoft ma resta comunque un lavorone. Ci spenderesti
sicuramente piï¿œ tempo che comprare un kit pronto all'uso
> Ciao e grazie
> RobertoA
Prego
--



text:
"Raffaele Rialdi [MVP]" <
malta@n0spam_vevy.com
> ha scritto nel messaggio
news:mn.5ad37db7b...@n0spamvevy.com...
> RobertoA wrote:
>> Il fatto e' che tutta la documentazione relativa a rpc e dcom viene vista
>> sempre da dentro un ambiente Microsoft Windows
>> 'trasportare' il tutto (o almeno la parte che mi interessa) su di una
>> schedina proprietaria mi sembra un'impresa titanica a meno di trovare
>> delle funzionalita' gia' belle e pronte esattamente per il micro che
>> usero', e su questo gia' c'ho messo una pietra sopra
>> Poi, per avere la documentazione adeguata su opc client/server bisogna
>> 'arruolarsi' tra i partner sostenitori di OpcConnect e li vanno fuori
>> qualche migliaio di euro
>
> Guarda se questo link ti può essere utile:
>
http://www.opcconnect.com/source.php
Grazie
Avevo gia' visto la documentazione disponibile in quella pagina
A parte alcune procedure in Delphi, tutti gli alri anche se c'e' scritto
Free dispongono di librerie che integrano i meccanismi principali
Librerie che ovviamente non sono gratuite e neanche visibili a meno di
acquistare i sorgenti
Ciao e grazie
RobertoA


title: EF - Navigation property

text:
Ciao,
sto cercando di creare il mio primo modello EF4.
Ho un database e sto cercando di caricare 3 semplice tabelle.
Sul database ho anche creato un diagram e possiamo considerare
l'esempio pari a quello che segue :
Persona
Auto
Telefono
Persona ha i seguenti campi : ID, nome, cognome, AutoID, TelefonoID
Auto : AutoID, Descrizione
Telefono : TelefonoID, Descrizione
Voglio ovviamente relazione Persona ad Auto e Telefono, tramite le
foreign key definite su SQL Server.
Purtroppo quello che succede è che EF non mi carica le navigation
property pur avendolo identificate.
Se se selezione inoltra un'associazione dal designer mi compare il
seguente messaggio : "Mapping are not alowed for an association over
exposed foreign keys".
Cosa significa e come posso arrivare a sistemare la situazione facendo
in modo che mi carichi e persista le classi tra loro correlate ?
Vi ringrazio,
Buona serata!


title: ThreadStaticAttribute e completamento di un thread

text:
Ciao a tutti,
ho un membro privato di una classe marcato con l'attributo
[ThreadStatic]: questo significa - se non ho capito male - che l'istanza
è "statica" ma nello scope di un thread, cioè se quel memebro viene
acceduto da due thread differenti, le istanze dell'oggetto coinvolte
saranno due istanze differenti.
So far, so good. :-)
Deduco che al completamento del thread l'oggetto verrà garbage collected
(quando il GC riterrà opportuno) e verrà richiamato il suo distruttore.
Ora, io invece avrei bisogno di poter richiamare alcuni metodi prima che
l'oggetto venga gettato nella spazzatura. E' possibile? Sapete
consigliarmi qualche strategia?
Grazie,
Giulio
p.s. per la cronaca: sto cercando di implementare una strategia
session-per-thread con la ISession di NHibernate. :-)
--


title: Reverse engineering

author: Stefano

text:
Ciao,
utilizzo da parecchio tempo la versione 2010 di VisualStudio Express e
volevo aggiornarmi alla 2013.
Non ho trovato chiari riferimenti in rete, questa versione supporta
Code Map ed/o il reverse engineering dei progetti oppure sono features
presenti unicamente nelle versioni superiori a pagamento?
Attualmente utilizzo NClass con il quale mi trovo bene, ma lo sviluppo
ed il supporto sono cessati tempo fa, purtroppo.
Grazie, ciao. Stefano.


title: espressioni Lambda e delegates in argomenti di metodi (tipo FindFirs di array e liste)

text:
Dunque, ho letto l'help e so che si possono istanziare
funzioni anonime monoriga direttamente negli argomenti
"attuali" di chiamata di certi metodi che prevedono delegati.
Potrei risolvere con addressof, ma essenzialmente vorrei
imparare a usare le espressioni di calcolo lambda (stile
funzionale diciamo).
Nell'esempio dell'help usa una funzione che incrementa di
uno, ma qualche anima pia, mi farebbe un esempio di funzione
a due argomenti interi, che li CONFRONTA per valore e
ritorna TRUE se uno è maggiore dell'altro, tale da poter
essere codificata inline come espressione lambda in un
metodo che si aspetta una delegate ?
Potrebbe essere tipo
MyList.Item.Find (function ... etc etc )(ValSoglia))
grazie in anticipo ... So che è una cosa un po complicata e
macchinosa, ma vorrei evitare di creare funzioni vere e
proprie a iosa solo per confrontare due stringhe in una lista.
ciao
Soviet


text:
Ciao Soviet_Mario,
You wrote on 03/04/2011 :
> Dunque, ho letto l'help e so che si possono istanziare funzioni anonime
> monoriga direttamente negli argomenti "attuali" di chiamata di certi metodi
> che prevedono delegati.
>
> Potrei risolvere con addressof, ma essenzialmente vorrei imparare a usare le
> espressioni di calcolo lambda (stile funzionale diciamo).
>
> Nell'esempio dell'help usa una funzione che incrementa di uno, ma qualche
> anima pia, mi farebbe un esempio di funzione a due argomenti interi, che li
> CONFRONTA per valore e ritorna TRUE se uno è maggiore dell'altro, tale da
> poter essere codificata inline come espressione lambda in un metodo che si
> aspetta una delegate ?
partiamo con una distinzione importantissima: delegate e expression
sono due cose abissalmente diverse, il primo è a tutti gli effetti un
puntatore a funzione con il notevole vantaggio di essere type-safe
mentre le expression sono una struttura dati atta a descrivere del
codice, le expression possono essere "compilate" e possono quindi
diventare dei delegate. C# ha introdotto la sintassi basata sulla
lambda e questa è condivisa sia dai delegate che appunto dalla lambda
expression.
detto questo immaginiamo questo scenario:
class Sample
{
   public event EventHandler SampleEvent;
}
dove EventHandler è un delegato la cui firma è una cosa del tipo:
delegate void EventHandler( object sender, EventArgs e );
sappiamo questo cosa vuol dire, nel tempo il linguaggio si è evoluto
molto e ci ha permesso i seguenti approcci:
Sample sample = new Sample();
sample.SampleEvent += new EventHandler( MyHandler );
void MyHandler( object sender, EventArgs e )
{
}
e poi questo:
Sample sample = new Sample();
sample.SampleEvent += delegate( object sender, EventArgs e )
{
}
quindi un anonymous delegate con una inline function; e infin con
l'arrivo delle lambda finalmente questo:
var sample = new Sample();
sample.SampleEvent += ( s, e ) =>
{
}
l'evoluzione se la vediamo così è molto naturale, e se ci fai caso non
ho messo "var" a caso, in realtà questa evoluzione è dovuta in parte
proprio a "var" o meglio all'introduzione degli "anonymous type" grazie
al concetto di type inference il compilatore è in grado di capire che
"sample" può essere solo ed esclusivamente di tipo "Sample", infatti
"var x = null" non è lecito. Allo stesso modo, quindi grazie a type
inference, il compilatore è in grado di capire che SampleEvent è un
delegato di EventHandler e che quindi l'unica firma possibile è
(Object, EventArgs) ergo "s" è di tipo object e "e" di tipo EventAergs.
Andando avanti sappiamo che un delegato in quanto puntatore a funzione
alla fine è un tipo come un altro (non proprio è varo è un po'
speciale) che può essere usato al di fuori del concetto di evento,
esistono quindi tutta una serie di delegati built-in che non hanno
nulla a che spartire con gli eventi:
delegate TResult Func<T1, T2, TResult>( T1 arg1, T2 arg2 );
che possono essere tranquillamente usati come parametri di una
funzione:
int ExecuteOperation( int first, int second, Func<int, int, int>
operationHandler )
{
   return operationHandler( first, second );
}
e che può essere chiamata così:
Func<int, int, int> handler = new Func<int, int, int>( funcHandler );
int funcHandler( int a, int b )
{
  //...
}
esattamente come gli eventi prima maniera, oppure per type inference
così:
Func<int, int, int> handler = ( a, b )
{
  return a + b;
}
vista la firma di Func<,,> "a" e "b" possono essere solo degli interi,
ergo infine possiamo anche scrivere questo:
class Operation
{
 public int ExecuteOperation( int first, int second, Func<int, int,
int> operationHandler )
 {
    return operationHandler( first, second );
 }
}
var op = new Operation();
var result = op.ExecuteOperation( 10, 12, (a, b) =>
{
  retur a + b;
} );
altro non abbiamo fatto che eliminare la dichiarazione della Func<,,> e
renderla inline nella chiamata al metodo. tutto il resto è type
inference.
> ciao
> Soviet
Spero di aver capito il dubbio e di aver dato un risposta utile.
.m
--
Mauro Servienti
{C67C0157-5D98-4733-A75E-93CAEE4BADC8}
Microsoft MVP - Visual C# / MCTS
http://mvp.support.microsoft.com
blog @
http://milestone.topics.it
whynot [ at ] topics [ dot ] it


text:
Il 03/04/2011 14:09, Mauro Servienti [MVP] ha scritto:
> Ciao Soviet_Mario,
>
> You wrote on 03/04/2011 :
>> Dunque, ho letto l'help e so che si possono istanziare funzioni
>> anonime monoriga direttamente negli argomenti "attuali" di chiamata di
>> certi metodi che prevedono delegati.
>>
>> Potrei risolvere con addressof, ma essenzialmente vorrei imparare a
>> usare le espressioni di calcolo lambda (stile funzionale diciamo).
>>
>> Nell'esempio dell'help usa una funzione che incrementa di uno, ma
>> qualche anima pia, mi farebbe un esempio di funzione a due argomenti
>> interi, che li CONFRONTA per valore e ritorna TRUE se uno è maggiore
>> dell'altro, tale da poter essere codificata inline come espressione
>> lambda in un metodo che si aspetta una delegate ?
>
intanto grazie della risposta, che mi studierò con calma
(fra l'altro MEA CULPA, non ho scritto che usavo VB, spero
di riuscire a trasferire qualcosa degli esempi C# che mi fai
dopo ... se no, magari scroccherò qualcos'altro :))
> partiamo con una distinzione importantissima: delegate e expression sono
> due cose abissalmente diverse, il primo è a tutti gli effetti un
> puntatore a funzione con il notevole vantaggio di essere type-safe
> mentre le expression sono una struttura dati atta a descrivere del
> codice,
uhm ... questo concetto purtroppo mi è del tutto oscuro.
Struttura dati che descrive del codice non mi dice nulla.
Anzi, ho qualche baco che mi porta a separare ciò che sono
dati da ciò che è codice ... Al più arrivo a capire codice
"di istanza", nel senso che nasconde un "this", in contrasto
agli shared che non cellanno
> le expression possono essere "compilate" e possono quindi
> diventare dei delegate. C# ha introdotto la sintassi basata sulla lambda
> e questa è condivisa sia dai delegate che appunto dalla lambda expression.
>
quanto mi dici è estrapolabile al VB ?
> detto questo immaginiamo questo scenario:
>
> class Sample
> {
> public event EventHandler SampleEvent;
> }
>
> dove EventHandler è un delegato la cui firma è una cosa del tipo:
>
> delegate void EventHandler( object sender, EventArgs e );
la firma sarebbe la dichiarazione di tipo (prototipo) ?
>
> sappiamo questo cosa vuol dire, nel tempo il linguaggio si è evoluto
> molto e ci ha permesso i seguenti approcci:
>
> Sample sample = new Sample();
> sample.SampleEvent += new EventHandler( MyHandler );
>
> void MyHandler( object sender, EventArgs e )
> {
>
> }
>
> e poi questo:
>
> Sample sample = new Sample();
> sample.SampleEvent += delegate( object sender, EventArgs e )
> {
>
> }
>
> quindi un anonymous delegate con una inline function; e infin con
> l'arrivo delle lambda finalmente questo:
>
> var sample = new Sample();
> sample.SampleEvent += ( s, e ) =>
> {
>
uhm, sorry, non riesco a pensarlo in termini di VB

non riesco a capirlo, forse mi hai risposto, ma non so
evincere le analogie col VB. E' già una caratteristica che
non capisco in VB stesso (e sebbene conosco il C++ benino,
non conosco il C# e le sue estensioni né la filosofia
managed). La tua spiegazione, di cui ti ringrazio, anche per
lo sviluppo esteso, è di livello superiore a quanto riesco a
capire ora come ora.
PRoverò a rifletterci ancora sopra.
grazie
Soviet
>
> .m
>


text:
Ciao Soviet_Mario,
You wrote on 03/04/2011 :
> intanto grazie della risposta, che mi studierò con calma
> (fra l'altro MEA CULPA, non ho scritto che usavo VB, spero di riuscire a
> trasferire qualcosa degli esempi C# che mi fai dopo ... se no, magari
> scroccherò qualcos'altro :))
prova a partire da qui, è più o meno lo stesso path che ho seguito io
in C#:
http://msdn.microsoft.com/en-us/magazine/cc163362.aspx
>> partiamo con una distinzione importantissima: delegate e expression sono
>> due cose abissalmente diverse, il primo è a tutti gli effetti un
>> puntatore a funzione con il notevole vantaggio di essere type-safe
>> mentre le expression sono una struttura dati atta a descrivere del
>> codice,
>
> uhm ... questo concetto purtroppo mi è del tutto oscuro.
> Struttura dati che descrive del codice non mi dice nulla. Anzi, ho qualche
> baco che mi porta a separare ciò che sono dati da ciò che è codice ... Al più
> arrivo a capire codice "di istanza", nel senso che nasconde un "this", in
> contrasto agli shared che non cellanno
ti faccio sempre un esempio in C# che è molto più congeniale:
Func<Boolean> f = () => return true;
un delgato, che ritorna sempre e solo "true", inutile ma alla fine è un
puntatore ad una funzione che può essere invocato così:
var result = f();
mentre attenzione, sintassi pressochè identica:
Expression<Func<Boolean>> ef = () => return true;
questo non piace al complatore:
var result = ef();
perchè ef non è un delegato ma è una Expression cioè una classe che
descrive il codice che sta dal lato destro dell' "="... ergo puoi fare
questo:
var f = ef.Compile();
var result = f();
se provi e vai a guardare "ef" con il debugger scopri un po' di cose
molto interessanti. Inoltre dai un occhio qui:
http://msdn.microsoft.com/en-us/library/bb397975.aspx
>
> quanto mi dici è estrapolabile al VB ?
certo che si :-)
>> detto questo immaginiamo questo scenario:
>>
>> class Sample
>> {
>> public event EventHandler SampleEvent;
>> }
>>
>> dove EventHandler è un delegato la cui firma è una cosa del tipo:
>>
>> delegate void EventHandler( object sender, EventArgs e );
>
> la firma sarebbe la dichiarazione di tipo (prototipo) ?
si, esattamente.
>>
>> sappiamo questo cosa vuol dire, nel tempo il linguaggio si è evoluto
>> molto e ci ha permesso i seguenti approcci:
>>
>> Sample sample = new Sample();
>> sample.SampleEvent += new EventHandler( MyHandler );
>>
>> void MyHandler( object sender, EventArgs e )
>> {
>>
>> }
>>
>> e poi questo:
>>
>> Sample sample = new Sample();
>> sample.SampleEvent += delegate( object sender, EventArgs e )
>> {
>>
>> }
>>
>> quindi un anonymous delegate con una inline function; e infin con
>> l'arrivo delle lambda finalmente questo:
>>
>> var sample = new Sample();
>> sample.SampleEvent += ( s, e ) =>
>> {
>>
>
> uhm, sorry, non riesco a pensarlo in termini di VB
>
prova a vedere se gli esempi del primo articolo sintatticamente
"suonano" meglio.



text:
Il 04/04/2011 11:32, Mauro Servienti [MVP] ha scritto:
> Ciao Soviet_Mario,
>
> You wrote on 03/04/2011 :
>> intanto grazie della risposta, che mi studierò con calma
>> (fra l'altro MEA CULPA, non ho scritto che usavo VB, spero di riuscire
>> a trasferire qualcosa degli esempi C# che mi fai dopo ... se no,
>> magari scroccherò qualcos'altro :))
>
> prova a partire da qui, è più o meno lo stesso path che ho seguito io in
> C#:
>
http://msdn.microsoft.com/en-us/magazine/cc163362.aspx
>
Me lo sto rileggendo varie volte ... è veramente ben fatto e
chiaro.
Non pensavo che si potessero persino annidare, per fare
delle factory ! !
Piccolo dubbio accessorio (non ho ancora letto il paragrafo
late binding, però, magari si risolve lì) : ma quelle lambda
annidate, sono risolte a compile-time come nei veri
template, o a runtime ?
E' un dubbio un po' ozioso, ma so che ad es. in C++ ci sono
dei simpatici fanatici che eseguono calcoli con template
annidati a compile time (praticamente una gara nello
scrivere il sorgente più lungo e intricato e l'eseguibile
più magro possibile ... tipo una costante :-).
cmq, grazie della consulenza, molto utile
ciao
Soviet
CUT
>


text:
Ciao Soviet_Mario,
You wrote on 05/04/2011 :
> Me lo sto rileggendo varie volte ... è veramente ben fatto e chiaro.
mi fa piacere.
> Non pensavo che si potessero persino annidare, per fare delle factory ! !
:-)
> Piccolo dubbio accessorio (non ho ancora letto il paragrafo late binding,
> però, magari si risolve lì) : ma quelle lambda annidate, sono risolte a
> compile-time come nei veri template, o a runtime ?
dipende, come ti dicevo in precedenza dobbiamo definire cosa significa
parlare di "lambda":
* se parlamo della sola sintassi funzionale, quindi ci limitiamo
all'uso dei delegati con la sintassi nuova allora fatto tutto il
compilatore a compile time;
* se parliamo di Expression Tree allora succede una cosa molto diversa,
o meglio hanno uno scopo molto diverso. In tutti i casi non c'è "late
binding" nel senso che la sintassi è type safe e lo ganrantisce il
compilatore a compile time.
Come ti dicevo gli expression tree hanno come scopo quello di poter
descrivere un blocco di codice principalemtne al fine di poter essere
analizzato da qualcosa (in gergo un Query Provider) che lo visita e lo
trasforma in qualcosa di comprensibile per un altro mondo. "Linq to
Sql" è il primo vero esempio di questo processo tu scrivi codice
C#/VB.Net e in realtà quello a runtime diventano delle chiamate ad un
database sql server... magie dell'interfaccia IQueryable e amiche varie
;-)
> cmq, grazie della consulenza, molto utile
.m



title: [C#, WPF 4] Bug (?) DataGrid e colorazione condizionale delle righe

text:
In una window di WPF4, una datagrid deve essere popolata con una serie
di istanze di una classe Issue, ognuna delle quali ha una certa priorità.
Sfruttando l'evento _LoadingRow della datagrid, effettuo via codice una
colorazione condizionale delle righe in base all'attributo
Issue.priority. Tutto va bene finché non faccio lo scroll delle righe
che non sono visibili, che vengono puntualmente colorate a cassaccio...
è un bug noto?
ps: dimenticavo di dire che uso la datagrid standard di WPF4.


text:
Ciao dedalus,
You wrote on 27/06/2011 :
> Sfruttando l'evento _LoadingRow della datagrid, effettuo via codice una
> colorazione condizionale delle righe in base all'attributo Issue.priority.
> Tutto va bene finchï¿œ non faccio lo scroll delle righe che non sono visibili,
> che vengono puntualmente colorate a cassaccio... ï¿œ un bug noto?
non direi mi sa che sei incappato nella non conoscenza di come ragiona
il motore di generazione degli item di un ItemsControl, questo ï¿œ un
ottimo motivo per usare stili e template e non incrocchiarsi usando
tecniche in stile windows forms.
quello che potrebbe succedere nel tuo caso, dico potrebbe perchï¿œ ci
sono n casistiche possibili, ï¿œ che l'ItemsContainerGenerator stia
riciclando gli ItemContainer che sono preposti a ospitare la riga della
griglia.
A grandi linee succede che scrolli di 5 righe, ad esempio, quindi 5
righe escono dalla vista corrente e 5 ne entrano, bene 5 ItemsContainer
vengono "spostati" in basso pronti per ospitare le 5 nuove righe.
Quando avviene questa operazione l'ItemsContainerGenerator non sa nulla
di colori e quindi le tue impostazioni vengono spostate insieme agli
elementi. Se invece usi stili e template tutto funziona come ti
aspetti.
.m
--
Mauro Servienti
{C67C0157-5D98-4733-A75E-93CAEE4BADC8}
Microsoft MVP - Visual C# / MCTS
http://mvp.support.microsoft.com/profile/mauro
blog @
http://milestone.topics.it
whynot [ at ] topics [ dot ] it


text:
On 27/06/2011 21:31, Mauro Servienti [MVP] wrote:
> Quando avviene questa operazione l'ItemsContainerGenerator non sa nulla
> di colori e quindi le tue impostazioni vengono spostate insieme agli
> elementi. Se invece usi stili e template tutto funziona come ti aspetti.
Esattamente: mi era sfuggito anche se è chiaramente specificato
http://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid.unloadingrow.aspx
Gestisco l'evento unloadrows della griglia e tutto funziona come mi aspetto.
Ciao e grazie.
Pasquale.


text:
Ciao dedalus,
You wrote on 28/06/2011 :
> On 27/06/2011 21:31, Mauro Servienti [MVP] wrote:
>> Quando avviene questa operazione l'ItemsContainerGenerator non sa nulla
>> di colori e quindi le tue impostazioni vengono spostate insieme agli
>> elementi. Se invece usi stili e template tutto funziona come ti aspetti.
>
> Esattamente: mi era sfuggito anche se ï¿œ chiaramente specificato
>
http://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid.unloadingrow.aspx
>
> Gestisco l'evento unloadrows della griglia e tutto funziona come mi aspetto.
ottimo, grazie a te per il feedback.
> Ciao e grazie.
> Pasquale.



title: Programmatore dotnet freelance

author: Federico Luciani

text:
Salve,
sono alla ricerca di un esperto .net per le modifiche di alcuni
applicativi.
E' gradita la disponibilità nelle ore non ufficio.
Per contatti:
turkhan2005[toglierequesto]@
gmail.com
saluti,
Federico.