我正在开发一个 WPF 用户控件,我希望它显示一些设计时数据。事实证明,要把事情做好是一个相当大的挑战,我真的可以使用你的帮助。
到目前为止,这是我的控制,基本上是<ListBox>
:
<UserControl x:Class="TA.Weather.UI.Wpf.WorkingSetEditor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Loaded="HandleLoadedEvent"
>
<Grid d:DataContext="{d:DesignData Source=/SampleData/WorkingSet.xaml}">
<ListBox x:Name="WorkingSetListBox" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="30" />
<ColumnDefinition MinWidth="30" />
<ColumnDefinition MinWidth="30" />
<ColumnDefinition MinWidth="30" />
<ColumnDefinition MinWidth="30" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" TextAlignment="Center"
Text="{Binding Path=[0].Limits.StationId}"></TextBlock>
<TextBlock Grid.Column="1" TextAlignment="Center"
Text="{Binding Path=[0].Limits.SensorId}"></TextBlock>
<TextBlock Grid.Column="2" TextAlignment="Center"
Text="{Binding Path=[0].Limits.SensorName}"></TextBlock>
<TextBlock Grid.Column="3" TextAlignment="Center"
Text="{Binding Path=[0].Limits.LowerLimit}"></TextBlock>
<TextBlock Grid.Column="4" TextAlignment="Center"
Text="{Binding Path=[0].Limits.UpperLimit}"></TextBlock>
<CheckBox Grid.Column="5" x:Name="MonitoredCheckBox"
IsChecked="{Binding Path=[1].Monitored}"/>
</Grid>
</ListBox>
</Grid>
</UserControl>
我想出了如何在另一个 XAML 文件中创建设计时数据,并将构建操作设置为DesignDataWithDesignTimeCreatableTypes
. 该类型本质上只是一个 DTO,因此在设计时创建实例似乎没问题。所以这里是数据文件,包含一个List<SensorState>
有两个成员的:
<generic:List x:TypeArguments="ws:SensorState"
xmlns:ws="clr-namespace:TA.Weather.Core;assembly=TA.Weather.Core"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:generic="clr-namespace:System.Collections.Generic;assembly=mscorlib">
<ws:SensorState IdleTimeout="300" LastUpdate="2015-08-19T03:39:00.000Z" Monitored="False"
WithinAcceptableLimits="False">
<ws:SensorState.Limits>
<ws:SensorLimits StationId="12-34-56-78-90-12" SensorId="1" SensorName="Inside Temperature"
LowerLimit="-10" UpperLimit="30" />
</ws:SensorState.Limits>
</ws:SensorState>
<ws:SensorState IdleTimeout="300" LastUpdate="2015-08-19T03:39:00.000Z" Monitored="True"
WithinAcceptableLimits="False">
<ws:SensorState.Limits>
<ws:SensorLimits StationId="12-34-56-78-90-12" SensorId="1" SensorName="Inside Temperature"
LowerLimit="-10" UpperLimit="30" />
</ws:SensorState.Limits>
</ws:SensorState>
</generic:List>
所以,某种意义上的成功。但是,此时有两个问题:
- 当列表中有两个项目时,为什么只显示一行?我可以通过更改绑定表达式中的数组索引来控制显示哪个实例,但是如何让行重复?我尝试删除数组索引,但这只会产生编译错误。
- 我收到“无法识别或无法访问成员 XXX”形式的数据文件的错误,我正在设置的每个属性都有一个错误,总共 36 个。即使构建成功并且设计时数据显示在编辑器中。它们是错误,所以我确信它们很重要——我只是不知道编译器试图告诉我什么。那么这些错误是什么意思,我需要做些什么来减轻它们呢?
还有更多。我想使用 aDataTemplate
为数据创建更好的外观;稍后会有一个用于设置限制等的滑块控件,所以这是我尝试使用模板的方式:
<UserControl x:Class="TA.Weather.UI.Wpf.WorkingSetEditor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:core="clr-namespace:TA.Weather.Core;assembly=TA.Weather.Core"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Loaded="HandleLoadedEvent"
>
<Grid d:DataContext="{d:DesignData Source=/SampleData/WorkingSet.xaml}">
<Grid.Resources>
<DataTemplate x:Key="WorkingSetTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="30" />
<ColumnDefinition MinWidth="30" />
<ColumnDefinition MinWidth="30" />
<ColumnDefinition MinWidth="30" />
<ColumnDefinition MinWidth="30" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" TextAlignment="Center"
Text="{Binding Path=[0].Limits.StationId}"></TextBlock>
<TextBlock Grid.Column="1" TextAlignment="Center"
Text="{Binding Path=[0].Limits.SensorId}"></TextBlock>
<TextBlock Grid.Column="2" TextAlignment="Center"
Text="{Binding Path=[0].Limits.SensorName}"></TextBlock>
<TextBlock Grid.Column="3" TextAlignment="Center"
Text="{Binding Path=[0].Limits.LowerLimit}"></TextBlock>
<TextBlock Grid.Column="4" TextAlignment="Center"
Text="{Binding Path=[0].Limits.UpperLimit}"></TextBlock>
<CheckBox Grid.Column="5" x:Name="MonitoredCheckBox"
IsChecked="{Binding Path=[1].Monitored}"/>
</Grid>
</DataTemplate>
</Grid.Resources>
<ListBox x:Name="WorkingSetListBox" ItemTemplate="{DynamicResource WorkingSetTemplate}">
</ListBox>
</Grid>
</UserControl>
所以基本上,我已经从资源中<Grid>
移出<ListBox>
和移入<DataTemplate>
。一旦我这样做了,设计时数据就消失了,我在设计器中只剩下一个空白控件。所以我的第三个问题变成了:
- 为什么我使用 a 时设计时数据会消失
<DataTemplate>
?我需要做些什么不同的事情?
您可能会说我几乎没有使用 WPF 的经验......我必须承认我在绑定表达式方面有点挣扎,它们看起来像是某种神秘的魔法,几乎没有押韵或理由。我想也许我在某个地方遗漏了一个重要的概念。我希望你能给我一些明智的话,把我推向正确的方向。