2008-10-15 17 views
8

Soy MUY nuevo en WPF, y todavía estoy tratando de ajustar mi enlace en XAML.WPF Encuadernación Colección My.Settings para los elementos de Combobox

Me gustaría rellenar un cuadro combinado con los valores de una colección de cadenas en my.settings. Puedo hacerlo en código como este:

Me.ComboBox1.ItemsSource = My.Settings.MyCollectionOfStrings

... y funciona.

¿Cómo puedo hacer esto en mi XAML? ¿Es posible?

Gracias

Respuesta

18

, se puede (y se debe en su mayor parte) declarar fijaciones en XAML, ya que esa es una de las características más potentes en WPF.

En su caso, para enlazar el cuadro combinado a uno de sus ajustes personalizados que utilizaría el siguiente XAML:

<Window x:Class="WpfApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:p="clr-namespace:WpfApplication1.Properties" 
    Title="Window1"> 
    <StackPanel> 
     <ComboBox 
      ItemsSource="{Binding Source={x:Static p:Settings.Default}, Path=MyCollectionOfStrings}" /> 
    </StackPanel> 
</Window> 

Aviso los siguientes aspectos:

  • declaramos un espacio de nombres XML con la prefijo 'p' que apunta al espacio de nombres .NET donde vive la clase 'Configuración' para referirse a él en XAML
  • Utilizamos la extensión de marcado '{Binding}' para declarar un enlace en XAML
  • se utilizó la extensión de marcado 'estático' con el fin de indicar que queremos referirnos a una estructura estática ('compartida' en VB) miembro de la clase en XAML
1

Es posible. En C#, que hacerlo de esta manera (por un simple bool):

IsExpanded="{Binding Source={StaticResource Settings}, Mode=TwoWay, Path=Default.ASettingValue}" 

que definen los recursos estáticos en "Configuración" en Application.Resources de mi App.xaml así:

<!-- other namespaces removed for clarity --> 
<Application xmlns:settings="clr-namespace:DefaultNamespace.Properties" > 
<Application.Resources> 
    <ResourceDictionary> 
    <settings:Settings x:Key="Settings" /> 
    <!--stuff removed--> 
    </ResourceDictionary> 
</Application.Resources> 
</Application> 

Su trayectoria puede sé diferente; en C#, accede a la configuración de la aplicación en su aplicación a través de

DefaultNamespace.Properties.Settings.Default.ASettingValue 
1

¡Lo tiene!

<Window x:Class="Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:p="clr-namespace:WpfApplication1" 
    Title="Window1" Height="90" Width="462" Name="Window1"> 
    <Grid> 
     <ComboBox ItemsSource="{Binding Source={x:Static p:Settings.Default}, Path=MyCollectionOfStrings}" /> 
    </Grid> 
</Window> 

Gracias a todos por ayudarme a alcanzar un gran "Aha!" momento :-) ... espero que después de pasar más tiempo en WPF, entienda por qué esto funciona.

+3

¿Qué tal marcando las respuestas como "contestado"? :) –

+0

Puede haber una respuesta mejor aquí, pero han pasado dos años desde que el problema estaba fresco en mi mente y rara vez trabajo con WPF ahora. así que marcaré mi última publicación aquí como la respuesta. –

+3

WTF ??? ¿Por qué no simplemente marcar la respuesta de Enrico como Respuesta en lugar de copiarla y marcar su propia respuesta? Robar es malo, ¿está bien? – Dimitri

3

Tengo una solución más simple para hacer eso, usando una extensión de marcado personalizada. En su caso se podría utilizar como esto:

<Window x:Class="Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:my="clr-namespace:WpfApplication1" 
    Title="Window1" Height="90" Width="462" Name="Window1"> 
    <Grid> 
     <ComboBox ItemsSource="{my:SettingBinding MyCollectionOfStrings}" /> 
    </Grid> 
</Window> 

Usted puede encontrar el código C# para esta extensión de marcado en mi blog aquí: http://www.thomaslevesque.com/2008/11/18/wpf-binding-to-application-settings-using-a-markup-extension/

0

También puede almacenar la lista como una cadena delimitada en los entornos luego usa un convertidor.

<ComboBox ItemsSource="{Binding Default.ImportHistory,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay,Converter={StaticResource StringToListConverter},ConverterParameter=|}" IsEditable="True"> 
/// <summary> 
/// Converts a delimited set of strings to a list and back again. The parameter defines the delimiter 
/// </summary> 
public class StringToListConverter : IValueConverter { 
/// <summary> 
/// Takes a string, returns a list seperated by {parameter} 
/// </summary> 
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { 
    string serializedList = (value ?? string.Empty).ToString(), 
      splitter = (parameter ?? string.Empty).ToString(); 
    if(serializedList.Trim().Length == 0) { 
     return value; 
    } 
    return serializedList.Split(new[] { splitter }, StringSplitOptions.RemoveEmptyEntries); 
} 
/// <summary> 
/// Takes a list, returns a string seperated by {parameter} 
/// </summary> 
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { 
    var items = value as IEnumerable; 
    var splitter = (parameter ?? string.Empty).ToString(); 
    if(value == null || items == null) { 
     return value; 
    } 
    StringBuilder buffer = new StringBuilder(); 
    foreach(var itm in items) { 
     buffer.Append(itm.ToString()).Append(splitter); 
    } 
    return buffer.ToString(0, splitter.Length > 0 ? buffer.Length - splitter.Length : buffer.Length); 
} 
} 

Luego, cuando se hace clic en un botón de navegación, se puede añadir a la lista:

var items = Settings.Default.ImportHistory.Split('|'); 
if(!items.Contains(dlgOpen.FileNames[0])) { 
Settings.Default.ImportHistory += ("|" + dlgOpen.FileNames[0]); 
} 
cboFilename.SelectedValue = dlgOpen.FileNames[0]; 
Settings.Default.Save();