为了保持MVVM之路,我几个小时都在努力完成以下任务:
我想显示特定Item的String-value(在TextBlock中),它是UserCollection(ObservableCollection<Tuple<int, string>>
)的一部分。选择应通过Collection中项目的Int-property进行,匹配MyOrder中绑定的IdCreatedByUser-Property。
为了使事情更清楚:
包含ID(int)和NAME(字符串)的UserCollection:
public ObservableCollection<Tuple<int, string>> UserCollection;
持有订单类实例的MyOrder-Property:
public Order MyOrder;
这是Orders-class的一个例子。
public class Order: INotifyPropertyChanged
{
public string Comment;
public int IdCreatedByUser;
public bool IsComplete;
}
请注意,这只是属性的一个示例..知道get,set在这里缺失..
我提出的唯一解决方案是劫持这样的Combox:
<ComboBox ItemsSource="{Binding UserCollection}"
DisplayMemberPath="Item2"
SelectedValue="{Binding MyOrder.IdCreatedByUser}"
SelectedValuePath="Item1">
<ComboBox.Template>
<ControlTemplate>
<TextBlock Text="{Binding SelectedItem.Item2,RelativeSource={RelativeSource Mode=TemplatedParent}}" />
</ControlTemplate>
</ComboBox.Template>
</ComboBox>
我可以使用ItemsSource,SelectedValue和SelectedValuePath,这使我可以选择并显示所需的项目。使用TextBlocks的任何解决方案? 我也在考虑转换器或额外的属性..但也许你可以告诉我一种方法来更好地设计它。 谢谢!
答案 0 :(得分:0)
这实际上使您的专用ComboBox可以轻松重复使用。像FontWeight
这样的东西将由ContentPresenter
继承。
<Style x:Key="CollectionLookupComboBox" TargetType="ComboBox" BasedOn="{StaticResource {x:Type ComboBox}}">
<!--
Default to readonly, but you can override that for particular instances
if that's useful somewhere.
-->
<Setter Property="IsReadOnly" Value="True" />
<Style.Triggers>
<Trigger Property="IsReadOnly" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<Border
x:Name="OuterBorder"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="Transparent"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Transparent"
>
<!--
The margin here keeps the text in the same spot when I toggle IsReadOnly,
with the default theme I have. May need to fiddle with that to get it to
look right for you.
-->
<ContentPresenter
Margin="3,2,2,0"
IsHitTestVisible="False"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
VerticalAlignment="Stretch"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
示例 - 这是过度的;你不需要ItemTemplate或粗体,但它演示了如何支持所有常用的ComboBox东西:
<StackPanel
Orientation="Vertical"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
>
<CheckBox
x:Name="ReadOnlyCheckBox"
IsChecked="True"
Margin="1"
Content="Read-Only"
/>
<ComboBox
Margin="1"
Style="{StaticResource CollectionLookupComboBox}"
IsReadOnly="{Binding IsChecked, ElementName=ReadOnlyCheckBox}"
MinWidth="80"
SelectedIndex="0"
FontWeight="Bold"
Foreground="Green"
>
<ComboBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="DeepSkyBlue" BorderThickness="2" CornerRadius="4">
<Label Content="{Binding}" />
</Border>
</DataTemplate>
</ComboBox.ItemTemplate>
<sys:String>First Item</sys:String>
<sys:String>Second Item</sys:String>
</ComboBox>
</StackPanel>