我想要一个像这样的组合框:
但是在代码中没有办法做到这一点。我正在使用MVVM模式。所以我有一个观点:
<ComboBox Style="{StaticResource ComboStyle}" ItemsSource="{Binding ResultObjects}" SelectedItem="{Binding SelectedObject,Mode=TwoWay}" />
和ViewModel:
public IEnumerable<DateTime> ResultObjects { get;set; }
public DateTime SelectedObject{ get;set; }
事实是-All-和-custom-不是DateTime。它不能添加到此列表中。 我记得在MVC中我们有一个“Dropdown helper”。
我在MVVM中可以做什么?
答案 0 :(得分:2)
您可以绑定到IEnumerable<KeyValuePair<DateTime?, string>>
,其中键表示实际值,值表示该值的自定义字符串表示形式:
public IEnumerable<KeyValuePair<DateTime?, string>> ResultObjects { get; set; }
public DateTime? SelectedObject { get; set; }
...
ResultObjects = new List<KeyValuePair<DateTime?, string>>()
{
new KeyValuePair<DateTime?, string>(null, "All"),
new KeyValuePair<DateTime?, string>(new DateTime(2018,04,17), new DateTime(2018,04,17).ToString("yyyy/MM/dd")),
new KeyValuePair<DateTime?, string>(new DateTime(2018,04,17), new DateTime(2018,04,17).ToString("yyyy/MM/dd @ HH:mm:ss")),
new KeyValuePair<DateTime?, string>(new DateTime(2018,04,17), "Custom...")
};
...
<强> XAML:强>
<ComboBox
ItemsSource="{Binding ResultObjects}"
SelectedValue="{Binding SelectedObject}"
DisplayMemberPath="Value"
SelectedValuePath="Key"/>
如果您希望能够代表其他类型的值,那么除非DateTime
中的实际IEnumerable<DateTime>
值,否则您无法返回任何内容,而应该更改源集合的类型。
答案 1 :(得分:1)
我处理此问题的方法是定义ObservableCollection<object>
当wpf遇到呈现给ui的对象时,它首先会查看它是否为该事物定义了模板。如果它没有,它将在对象上使用ToString。对于简单的情况,您可以依赖它,并在您要使用的任何对象上覆盖.ToString()
如果您想要更复杂的显示而不仅仅是字符串,那么您可以根据数据类型定义一个以对象为目标的数据窗口。
一个可以派上用场的伎俩
您甚至可以从一个基础对象继承并为其定义模板,然后为子类型定义更具体的模板。从您的基础对象继承的子类型将由您的&#34;默认&#34;处理。
EG。
我有一个地图编辑器。用户正在从他将要绘制的不同地形中进行选择。我想为这些显示不同的东西。我有一个BaseTerrainVM,然后我继承了河流,轮廓,树林等。
这是我用来模板列表框中项目的标记的子集:
<ListBox.Resources>
<DataTemplate DataType="{x:Type local:BaseTerrainVM}">
<Grid>
<TextBlock Text="{Binding DisplayType}" HorizontalAlignment="Left"
VerticalAlignment="Center"/>
<TextBlock Text="{Binding ID}"
HorizontalAlignment="Right"
VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type local:ContourVM}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding DisplayType}"
Grid.Column="0"
VerticalAlignment="Center"/>
<StackPanel Orientation="Horizontal"
Grid.Column="1"
TextElement.FontFamily="Century Gothic"
TextElement.FontSize="{DynamicResource LargeFont}"
TextElement.FontWeight="Normal"
>
<TextBox MinWidth="50"
Text="{Binding Height}"
GotKeyboardFocus="TextBox_GotKeyboardFocus"
>
<i:Interaction.Behaviors>
<ui:TextBoxDecimalRangeBehaviour MaxDecimals="0"
MaxInteger="3"
Minimum="{StaticResource Zero}"
Maximum="{StaticResource TwoFiveFive}" />
<ui:SelectAllTextBoxBehavior/>
</i:Interaction.Behaviors>
</TextBox>
<TextBlock Text="units"
Margin="2,0,0,0"
ToolTip="Elevation is represented by a number 0-255 which is multiplied by a factor to give metres"
/>
</StackPanel>
<TextBlock Text="{Binding ID}"
Grid.Column="2"
VerticalAlignment="Center"
/>
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type local:RiverVM}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding DisplayType}"
Grid.Column="0"
VerticalAlignment="Center"/>
<StackPanel Orientation="Horizontal"
Grid.Column="1"
TextElement.FontFamily="Century Gothic"
TextElement.FontSize="{DynamicResource LargeFont}"
TextElement.FontWeight="Normal"
>
<Button
Command="{Binding PressureFromStartCommand}"
Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
Height="20"
ToolTip="Widen from Start of stroke"
>
<Path Data="{StaticResource FlowRight}"
Stretch="Uniform"
Fill="LightBlue"
Stroke="DodgerBlue"
StrokeThickness="1"
/>
</Button>
<Button
Command="{Binding PressureConstantCommand}"
Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
Height="20"
ToolTip="Constant width for river"
>
<Rectangle
Width="18"
Height="6"
Fill="LightBlue"
Stroke="DodgerBlue"
StrokeThickness="1"
/>
</Button>
<Button
Command="{Binding PressureFromEndCommand}"
Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
Height="20"
ToolTip="Widen from End of stroke"
>
<Path Data="{StaticResource FlowRight}"
Stretch="Uniform"
Fill="LightBlue"
Stroke="DodgerBlue"
StrokeThickness="1"
RenderTransformOrigin="0.5,0.5"
>
<Path.RenderTransform>
<ScaleTransform ScaleX="-1" ScaleY="1" />
</Path.RenderTransform>
</Path>
</Button>
</StackPanel>
<TextBlock Text="{Binding ID}"
Grid.Column="2"
VerticalAlignment="Center"
/>
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type local:BoundaryVM}">
<Grid>
(这可能会让泥浆变得有趣。)
我展示这些的Terrains实际上是一个复合系列。在我的情况下,这是因为我将地图上的所有水转化为一个物体,因此在一条道路与下一条道路之间没有边界,或者湖泊和河流流入其中。我需要提出水的两种表示形式,但要在它们之间切换。
答案 2 :(得分:0)
您需要使用CompositeCollection
,它可以处理多个集合和其他对象。
尝试这样的事情
<ComboBox>
<ComboBox.ItemsSource>
<CompositeCollection>
<ComboBoxItem Content="--All--" />
<CollectionContainer Collection="{Binding Source=ResultObjects}" />
<ComboBoxItem Content="--Custom--" />
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>