Добавьте коллекцию или массив в словарь ресурсов wpf
-
21-09-2019 - |
Вопрос
Я искал повсюду и не могу найти ответа на этот вопрос.У меня есть два вопроса
- Как вы создаете массив или коллекцию в 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
2-й.Я попытался сослаться на объединенный словарь ресурсов в моем XAML и столкнулся с проблемами, потому что в Window.resources у меня было больше, чем просто словарь, поэтому мне потребовалось добавить x: Key.Как только я добавляю ключ, система больше не может находить элементы в моем словаре ресурсов.Вместо этого мне пришлось переместить объединенный словарь в Grid.Resources.В идеале я хотел бы ссылаться на объединенный словарь в app.xaml, но у меня та же проблема
Вот несколько примеров кода.Для этой первой части требовался x: key для компиляции, потому что у меня есть converter, и он жаловался, что у каждого элемента должен быть ключ, если их несколько
<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>
Спасибо
Решение
Насколько я понимаю вашу проблему, вы хотите связать 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
собственность (из Любой 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>
Надеюсь, это поможет.
С уважением,
Михир Гокани
Другие советы
Пожалуйста, поправьте меня, если я ошибаюсь, но я думаю, вы хотите что-то подобное?
<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}"
Что касается ресурсов, вам просто нужно переместить ваш дополнительный конвертер во вновь объявленный ResourceDictionary:
<App.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ResourcesD.xaml" />
</ResourceDictionary.MergedDictionaries>
<win:BooleanToVisibilityConverter x:Key="VisibilityConverter" />
</ResourceDictionary>
</App.Resources>
Если вы добавите словарь ресурсов внутри ресурсов Window, вы не сможете получить к нему доступ повсюду, вместо этого вы должны добавить в ресурсы "App" (проверьте файл App.xaml).
<App.Resources>
<win:BooleanToVisibilityConverter x:Key="VisibilityConverter" />
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ResourcesD.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</App.Resources>
Это будет доступно в каждом объекте WPF независимо от создания какой-либо иерархии наследования.