Привязка к проектным данным в WPF
У меня есть окно WPF, содержащее ListBox. ItemsSource связан со свойством модели представления.
<Window x:Class="SimpleWpfApp.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
DataContext="{Binding MainWindowViewModel, Source={StaticResource Locator}}">
<DockPanel>
<ListBox ItemsSource="{Binding SomeThings}" />
</DockPanel>
</Window>
Свойство модели представления является наблюдаемой коллекцией пользовательского интерфейса; ISomeInterface. Интерфейс очень прост и реализован SomeClass, который дополнительно переопределяет ToString.
public class MainWindowViewModel
{
public ObservableCollection<ISomeInterface> SomeThings
{
get
{
var list = new List<ISomeInterface>
{
new SomeClass {Value = "initialised"},
new SomeClass {Value = "in"},
new SomeClass {Value = "code"}
};
return new ObservableCollection<ISomeInterface>(list);
}
}
}
public interface ISomeInterface
{
string Value { get; }
}
public class SomeClass : ISomeInterface
{
public string Value { get; set; }
public override string ToString() => Value;
}
Когда я просматриваю окно в Visual Studio 2015 или Blend, все происходит так, как ожидалось. Вызов ToString и заполнение ListBox.
Я создал данные дизайна XAML, которые хочу использовать в режиме разработки. Я добавил данные дизайна в каталог с именем SampleData. Я добавляю оператор Datacontext в окно XAML, расположенное непосредственно под первым DataContext.
d:DataContext="{d:DesignData Source=/SampleData/Data.xaml}"
Это не работает Visual Studio и Blend сообщают "Файл или элемент проекта не найден" независимо от того, что я использую для исходного пути. Я пробовал /SampleData/Data.xaml, SampleData / Data.xaml,../SampleData/Data.xaml,./../SampleData/Data.xaml
Visual Studio и Blend находят Data.xaml только тогда, когда я перемещаю его из каталога SampleData в корень проекта. Затем я могу ссылаться на него, используя исходный путь /Data.xaml или Data.xaml. Если я использую Data.xaml без префикса /, тогда Visual Studio и Blend сообщают, что файл не может быть найден... но все равно его находят.
Мой первый вопрос... Могу ли я использовать примеры данных в подкаталоге? И если так, как?
После успешной ссылки на Data.xaml в корне проекта мое окно не вызывает переопределенную ToString, поэтому я получаю список отображаемых имен классов. Список имеет то же количество элементов, что и данные проекта, поэтому, похоже, он использует данные проекта.
Мой второй вопрос: почему переопределенная ToString не вызывается здесь, когда это происходит, если объекты создаются из кода?
Я знаю, что могу достичь желаемого результата, указав шаблон элемента.
<ListBox ItemsSource="{Binding SomeThings}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Полный исходный код доступен для примера приложения на github.
https://github.com/DangerousDarlow/WpfDesignData
ОБНОВИТЬ
Спасибо jstreet за ответ. Я изменил свойства файла для data.xaml в подкаталоге и теперь могу использовать его в качестве проектных данных. Я думал, что попробовал это раньше, но я должен ошибаться.
Я до сих пор не вижу, чтобы ToString вызывали. Я попытался изменить свойство модели представления на List<object>
а также List<ISomeInterface>
но оба привели к вызову object.ToString; выводится отображением имени класса. Я, вероятно, перестану смотреть на этот момент, так как в любом случае я не собираюсь использовать ToString, я свяжусь со свойствами, которые я хочу отобразить. Хотя было бы хорошо объяснить разницу в поведении.
Я использую Visual Studio 2015 Community Edition.
1 ответ
Вот пример рабочего кода. Вы можете обратиться к этой статье - MSDN.
В частности, обратите внимание, как установить свойства для вашего Data.xaml
файл (Dictionary1.xaml, в моем случае) в вашем проекте VS:
Также обратите внимание, как создать свой корневой объект, SomeThings
(SomeClasses в моем случае):
Для коллекций корневым объектом может быть ArrayList или пользовательский тип, производный от коллекции или универсальной коллекции...
XAML:
<Window x:Class="WpfApplication277.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication277"
d:DataContext="{d:DesignData Source=/SampleData/Dictionary1.xaml}"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ListView ItemsSource="{Binding}"></ListView>
</Grid>
Dictionary1.xaml:
Щелкните правой кнопкой мыши SampleData
папку в вашем проекте VS и выберите Add \ New Item \ WPF \ Resource Dictionary, замените его содержимое данными проекта. Это должно гарантировать, что ваши данные дизайна могут быть расположены в подпапке.
<m:SomeClasses xmlns:m="clr-namespace:WpfApplication277">
<m:SomeClass Value="design data 1">
</m:SomeClass>
<m:SomeClass Value="design data 2">
</m:SomeClass>
<m:SomeClass Value="design data 3">
</m:SomeClass>
SomeClasses: List<SomeClass>
не работает!
public class SomeClasses : List<Object>
{
public SomeClasses() { }
}
SomeClass:
public class SomeClass : ISomeInterface
{
public string Value { get; set; }
public override string ToString() => string.Format("ToString() : {0}",Value);
}
Обратите внимание, что ToString()
определенно называется: