我有一个ComboBox
,其中包含不同的部分,每个部分的标题分别为Video
,Audio
,Image
。
我使用XAML
Style
,在页眉上方添加了7px
边距,以使各节分开。
如何仅删除第一个标题的页边距,使其与ComboBox
的顶部齐平?
我尝试将ComboBox
<Grid>
设置为Margin="0,-7,0,0"
,但它适用于所有项目。
<ComboBox x:Name="cboContainer"
ItemsSource="{Binding Format_Container_Items}"
SelectedValuePath="Name"
SelectedValue="{Binding Format_Container_SelectedItem, Mode=TwoWay}"
Style="{DynamicResource ComboBoxCustom}"
ItemContainerStyle="{DynamicResource ComboBoxCustomItem}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="105"
Height="22"
Margin="0,2,0,0">
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock DataContext="{Binding}">
<TextBlock.Text>
<Binding Path="Name"/>
</TextBlock.Text>
</TextBlock>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Style x:Key="ComboBoxCustomItem" TargetType="{x:Type ComboBoxItem}">
<Setter Property="Template" Value="{StaticResource ComboBoxCustom.Item.ControlTemplate}"/>
<Setter Property="Foreground" Value="#FF000000" />
<Setter Property="Background" Value="#FFFFFFFF" />
<Setter Property="BorderBrush" Value="#FFFFFFFF" />
<Style.Triggers>
<!-- Selected -->
<Trigger Property="IsSelected" Value="true">
<Setter Property="Foreground" Value="{StaticResource ComboBoxCustom.Static.Foreground}" />
<Setter Property="Background" Value="{StaticResource ComboBoxCustom.Static.Background}" />
</Trigger>
<!-- Mouse Over -->
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="{StaticResource ComboBoxCustom.MouseOver.Foreground}" />
<Setter Property="Background" Value="{StaticResource ComboBoxCustom.MouseOver.Background}" />
</Trigger>
<!-- Headers -->
<DataTrigger Binding="{Binding IsHeader}" Value="True">
<Setter Property="IsEnabled" Value="False"/>
<Setter Property="FontWeight" Value="Bold"/>
<!-- 7px Margin Applied Here -->
<Setter Property="Margin" Value="0,7,0,0"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsHeader}" Value="False">
<Setter Property="Margin" Value="0,0,0,0"/>
</DataTrigger>
</Style.Triggers>
</Style>
public class FormatContainer
{
public string Name { get; set; }
public bool IsHeader { get; set; }
}
public List<FormatContainer> _Format_Container_Items = new List<FormatContainer>()
{
new FormatContainer() { Name = "Video", IsHeader = true },
new FormatContainer() { Name = "webm", IsHeader = false },
new FormatContainer() { Name = "mp4", IsHeader = false },
new FormatContainer() { Name = "mkv", IsHeader = false },
new FormatContainer() { Name = "Audio", IsHeader = true },
new FormatContainer() { Name = "mp3", IsHeader = false },
new FormatContainer() { Name = "m4a", IsHeader = false },
new FormatContainer() { Name = "ogg", IsHeader = false },
new FormatContainer() { Name = "Image", IsHeader = true },
new FormatContainer() { Name = "jpg", IsHeader = false },
new FormatContainer() { Name = "png", IsHeader = false },
new FormatContainer() { Name = "webp", IsHeader = false },
};
public List<FormatContainer> Format_Container_Items
{
get { return _Format_Container_Items; }
set
{
_Format_Container_Items = value;
OnPropertyChanged("Format_Container_Items");
}
}
答案 0 :(得分:2)
对于问题本身,您只需要一个ItemsPanelTemplate
。
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Margin="0 -7 0 0"/>
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
但是为了正确执行所需的操作,我强烈建议您将数据结构更改为
public class FormatContainer
{
public string Name { get; set; }
public string Category { get; set; }
}
然后将Format_Container_Items
的视图与Category
进行分组,并使用ComboBox.GroupStyle自定义演示文稿。
答案 1 :(得分:2)
您可以定义另一个属性,例如 IsFirstHeader ,并仅向其添加边距。
答案 2 :(得分:1)
如果我是在商业应用程序中执行此操作,则可能会在FormatContainer中公开一个属性,以向视图指示列表中的哪个元素是第一个元素,但是可以在XAML中使用相等的转换器来实现当任何两个项目相同时返回true:
public class EqualityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return Object.Equals(values[0], values[1]);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
然后在XAML中,您只需添加一个额外的DataTrigger并将其用作转换器,然后传入当前对象和原始列表中的第一个对象即可
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding>
<MultiBinding.Converter>
<conv:EqualityConverter />
</MultiBinding.Converter>
<Binding Path="DataContext.Format_Container_Items[0]" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ComboBox}" />
<Binding />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Margin" Value="0,0,0,0"/>
</DataTrigger>
我确实建议您使用常规的DataTrigger在视图模型中处理此问题。像我在这里使用的技术一样,它展示了WPF绑定引擎的强大功能,但是到最后,您仍然要向逻辑层添加逻辑代码,该层并不是它真正所属的,即使它是通用的转换器。
答案 3 :(得分:0)
不确定将其用作样式触发器时是否可以使用,请尝试一下。
<DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}" Value="{x:Null}">
<Setter Property="Margin" Value="0,0,0,0"/>
</DataTrigger>