PDA

View Full Version : [WPF] Combobox and bind dinamico


robertino_salemi
17-02-2015, 10:06
Ciao,
nella mia applicazione WPF, sto usando delle combobox e come ItemsSource eseguo il bind di una collection letta dal database, vorrei:
- eseguire un captalize dei vari item, qual è il modo migliore?
- come impostare la larghezza della stessa lunghezza dell'item più lungo presente?

Grazie.

[Kendall]
17-02-2015, 15:32
Il metodo più semplice che mi viene in mente è questo.


<ComboBox ItemsSource="{Binding}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding NomeProprietà}" CharacterCasing="Upper"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

robertino_salemi
17-02-2015, 15:40
Grazie Kendall,
ci siamo quasi, ma nel mio caso visualizzato anche DisplayMemberPath ottenendo così un'eccezione....


<ComboBox Name="cmbTypeOfSchedule"
DataContext="{StaticResource DomainDataViewModel}"
ItemsSource="{Binding SchedTypes}"
DisplayMemberPath="Description"
IsEditable="True" IsReadOnly="True" Text="{StaticResource menuCmbAll}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Description}" CharacterCasing="Upper"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

damxxx
17-02-2015, 16:52
Non puoi farlo nel codice invece che nello XAML?
Potresti applicare il metodo .ToUpper() alla proprietà o usare un converter (http://wpftutorial.net/ValueConverters.html)?

[Kendall]
17-02-2015, 17:20
Grazie Kendall,
ci siamo quasi, ma nel mio caso visualizzato anche DisplayMemberPath ottenendo così un'eccezione....


<ComboBox Name="cmbTypeOfSchedule"
DataContext="{StaticResource DomainDataViewModel}"
ItemsSource="{Binding SchedTypes}"
DisplayMemberPath="Description"
IsEditable="True" IsReadOnly="True" Text="{StaticResource menuCmbAll}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Description}" CharacterCasing="Upper"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>


Se usi un template devi rimuovere l'assegnazione alla proprietà DisplayMemberPath in quanto va in conflitto.

robertino_salemi
17-02-2015, 17:24
Sto tentando la strada del Converter, così da lasciare lo xmal più leggibile.

Vediamo se riesco a risolvere....

robertino_salemi
18-02-2015, 09:38
Ciao,
grazie della segnalazione.

Per il primo punto ho usato la classse IValueConverter:

public class StringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
SchedType obj = value as SchedType;

string description = obj.Description;

if (description == null)
return null;

if (description.Length > 1)
return char.ToUpper(description[0]) + description.Substring(1);

return description.ToUpper();
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}


Mi sono accorto che comunque non va, perchè nella combo viene riportato il valore modificato come da me desiderato con il captalize, ma se ne seleziono uno mi riporta il nome delll'object, come mai?

Nello XAML ho:
- definito il namespace

xmlns:localConvert="clr-namespace:MyAPP.Converters"

- all'interno della combobox ho

<ComboBox Name="cmbTypeOfSchedule"
DataContext="{StaticResource DomainDataViewModel}"
ItemsSource="{Binding SchedTypes}"
IsEditable="True" IsReadOnly="True" Text="{StaticResource menuCmbAll}">
<ComboBox.Resources>
<localConvert:StringConverterCapitalize x:Key="toCapitalize"/>
</ComboBox.Resources>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource toCapitalize}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>


Come mai?

Grazie.