Добавить коллекцию или массив в словарь ресурсов wpf - PullRequest
8 голосов
/ 19 марта 2010

Я ищу высоко и низко и не могу найти ответ на этот вопрос. У меня два вопроса

  1. Как создать массив или коллекцию в XAML. У меня есть массив, который я хочу вставить туда и связать со списком. Моей первой идеей было поместить ItemsControl в словарь ресурсов, но ItemsSource в поле со списком ожидает IEnumerable, чтобы он не работал.

Вот что я попробовал в своем словаре ресурсов, и ни один из них не работает

<ItemsControl x:Key="stateList">
    <sys:String>AL</sys:String>
    <sys:String>CA</sys:String>
    <sys:String>CN</sys:String>
</ItemsControl>
<ItemsControl x:Key="stateList2">
    <ComboBoxItem>AL</ComboBoxItem>
    <ComboBoxItem>CA</ComboBoxItem>
    <ComboBoxItem>CN</ComboBoxItem>
</ItemsControl>

и вот как я к нему привязываюсь

<ComboBox SelectedValue="{Binding Path=State}" ItemsSource="{Binding Source={StaticResource stateList2}}"  >

                    </ComboBox>

РЕДАКТИРОВАТЬ: ОБНОВЛЕНО

Я получил эту первую часть, чтобы работать таким образом

 <col:ArrayList x:Key="stateList3">
    <sys:String>AL</sys:String>
    <sys:String>CA</sys:String>
    <sys:String>CN</sys:String>
</col:ArrayList>

Однако я бы предпочел не использовать список массивов, я бы хотел использовать общий список, поэтому, если кто-нибудь знает, как, пожалуйста, сообщите мне.

РЕДАКТИРОВАТЬ ОБНОВЛЕНИЕ: Я полагаю, что XAML имеет очень ограниченную поддержку непатентованных средств, поэтому, возможно, список массивов - лучшее, что я могу сделать на данный момент, но я все же хотел бы получить помощь по второму вопросу, если у кого-то есть anser

второй. Я пытался ссылаться на словарь объединенных ресурсов в своем XAML, и у меня были проблемы, потому что в Window.resources у меня было больше, чем просто словарь, поэтому мне потребовалось добавить x: Key. Когда я добавляю ключ, система больше не может найти элементы в моем словаре ресурсов. Вместо этого мне пришлось переместить объединенный словарь в Grid.Resources. В идеале я хотел бы сослаться на объединенный словарь в app.xaml, но у меня та же проблема

Вот пример кода. Эта первая часть требует x: key для компиляции, потому что у меня есть конвертер, и он жаловался, что у каждого элемента должен быть ключ, если существует более одного

<UserControl.Resources>
    <win:BooleanToVisibilityConverter x:Key="VisibilityConverter" />
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/ResourcesD.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

Мне пришлось изменить это на

<UI:BaseStep.Resources>
    <win:BooleanToVisibilityConverter x:Key="VisibilityConverter" />             
</UI:BaseStep.Resources>
<Grid>
    <Grid.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/ResourcesD.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Grid.Resources>
</Grid>

Спасибо

Ответы [ 4 ]

16 голосов
/ 19 марта 2010

Насколько я понимаю вашу проблему, вы хотите связать ComboBox (или ListBox) с массивом элементов, верно? Если вам нужны элементы из какого-либо внешнего источника данных, вы можете просто использовать удобное свойство DataContext. Поиск MSDN для получения дополнительной информации по этому вопросу. Однако, если вы хотите ручную коллекцию, сделайте это следующим образом:

Создайте свой собственный класс:

public class StringCollection : ObservableCollection<string> { }

и теперь используйте его так:

<Window.Resources>
    <local:StringCollection x:Key="stringCollection">
        <sys:String>Hello</sys:String>
        <sys:String>World</sys:String>
    </local:stringCollection>
</Window.Resources>

...

    <ListBox
        Margin="15"
        ItemsSource="{StaticResource stringCollection}" />

Или, если вы хотите более общую коллекцию, создайте такой класс:

public class ObjectCollection : ObservableCollection<object> { }

и используйте его так:

    <local:ObjectCollection x:Key="objectCollection">
        <sys:String>Hello</sys:String>
        <TextBlock>World</TextBlock>
        <sys:Int32>12345</sys:Int32>
    </local:ObjectCollection>

    ...

    <ComboBox
        Margin="15"
        ItemsSource="{StaticResource objectCollection}" />



Вы также можете использовать некоторые встроенные классы, такие как Int32Collection, которые реализуют IEnumerable. Вы можете использовать их непосредственно как ресурс.


Свойство Resources (из any FrameworkElement подобно Window, UserControl или Application) имеет тип ResourceDictionary, но не является ресурсом коллекции словари! так что вы не можете сделать так:

<UserControl.Resources>

    <!-- The first RD -->
    <!--<ResourceDictionary>
        <win:BooleanToVisibilityConverter x:Key="VisibilityConverter" />
    </ResourceDictionary>-->

    <!-- Second RD!!! -->
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/ResourcesD.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

Вместо этого сделайте так:

<UserControl.Resources>

    <!-- 
        There should be only 1 main RD, 
        Merge other RDs, if any
     -->
    <ResourceDictionary>

        <!-- First Resource -->
        <win:BooleanToVisibilityConverter x:Key="VisibilityConverter" />

        <!-- Second Resource -->
        <ResourceDictionary.MergedDictionaries>
            <!-- Now, there can be multiple RDs -->
            <ResourceDictionary Source="/ResourcesA.xaml" />
            <ResourceDictionary Source="/ResourcesB.xaml" />
            <ResourceDictionary Source="/ResourcesC.xaml" />
            <ResourceDictionary Source="/ResourcesD.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>

</UserControl.Resources>

Надеюсь, это поможет.
С уважением,
Михир Гокани

1 голос
/ 19 марта 2010

Для ресурсов вам просто нужно переместить ваш дополнительный конвертер во вновь объявленный ResourceDictionary:

<App.Resources> 
    <ResourceDictionary> 
        <ResourceDictionary.MergedDictionaries> 
            <ResourceDictionary Source="/ResourcesD.xaml" /> 
        </ResourceDictionary.MergedDictionaries> 

    <win:BooleanToVisibilityConverter x:Key="VisibilityConverter" /> 
    </ResourceDictionary> 
</App.Resources> 
1 голос
/ 19 марта 2010

Пожалуйста, исправьте меня, если я ошибаюсь, но я думаю, что вы хотите что-то подобное?

<Grid.Resources>
  <local:MyCustomCollection x:Key="local:MyCustomCollection"/>
</Brid.Resources>

В верхней части окна у вас будет свойство:

xmlns:local="clr-namespace:MyNamespace"

И внутри вашего кода у вас будет:

MyCustomCollection  custCol = MyGrid.Resources["MyCustomCollection"] as MyCustomCollection;

Привязка произойдет для элемента управления со свойством, примерно таким:

ItemsSource="{StaticResource MyCustomCollection}"
0 голосов
/ 19 марта 2010

Если вы добавите словарь ресурсов в ресурсы Window, вы не сможете получить к нему доступ повсюду, вместо этого вам следует добавить ресурсы «App» (см. Файл App.xaml).

<App.Resources> 
    <win:BooleanToVisibilityConverter x:Key="VisibilityConverter" /> 
    <ResourceDictionary> 
        <ResourceDictionary.MergedDictionaries> 
            <ResourceDictionary Source="/ResourcesD.xaml" /> 
        </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</App.Resources> 

Это будет доступно в каждом объекте WPF независимо от создания какой-либо иерархии наследования.

...