如何将放置在拆分按钮内容中的标签文本与选定的列表框项绑定?



>我正在尝试使用 WPF 拆分按钮创建一个类似控件的下拉列表。我可以下拉工作,但我接下来要实现的是,如果用户从下拉菜单中选择一个项目,该文本将更新为拆分按钮内容。此外,默认情况下,加载此控件时,第一项名称设置为拆分按钮内容。

我更喜欢在 xaml 本身中执行此操作。

下面是现有代码:

<userControls:BaseUserControl x:Class="UserControls.TestControl"
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:userControls="clr-namespace:MainAssembly.UserControls"
xmlns:const="clr-namespace:MainAssembly.const"
xmlns:toolkit="abc/Wpf.Toolkit"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d" 
d:DesignHeight="450" d:DesignWidth="800">
<userControls:BaseUserControl.Resources>
<ResourceDictionary>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<toolkit:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
<toolkit:MultiValueToObjectArrayConverter x:Key="MultiValueToObjectArrayConverter" />
<toolkit:BoolToInvertedBoolToVisibilityConverter x:Key="BoolToInvertedBoolToVisibilityConverter" />
</ResourceDictionary>
</userControls:BaseUserControl.Resources>
<xctk:SplitButton Name="TestSplitBtn" ToolBar.OverflowMode="AsNeeded"
Margin="5,1,5,1"
>
<xctk:SplitButton.DropDownContent>
<ListBox Name="DropDownMenu" Margin="5,1,5,5"
ItemsSource="{Binding DropDownContentCollection}"
ToolBar.OverflowMode="AsNeeded"                                                                        
Visibility="{Binding DropDownContentCollection, Converter={StaticResource NullToVisibilityConverter}}"
ToolTip="{x:Static const:const.toolTip}"
MaxWidth="150">
<ListBox.ItemTemplate>
<DataTemplate>
<Button Style="{DynamicResource TransparentButton}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" Command="{Binding DataContext.TestCommand,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBox}}}" CommandParameter="{Binding}">
<Button.Content>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center">
<Rectangle Fill="{DynamicResource Icon_Test}" Margin="4,0,5,0" Height="16" Width="16" />
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center">
<TextBlock.Text>
<MultiBinding StringFormat="{} {0}({1})">
<Binding Path="Name" />
<Binding Path="ImageCount" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</Button.Content>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.Style>
<Style TargetType="{x:Type ListBox}" BasedOn="{StaticResource ListBoxStyle}">
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ListBoxItem">
<Setter Property="AutomationProperties.AutomationId" Value="{Binding Name}"/>
</Style>
</Setter.Value>
</Setter>
</Style>
</ListBox.Style>
</ListBox>
</xctk:SplitButton.DropDownContent>
<xctk:SplitButton.Content>
<toolkit:LabelledButton x:Name="TestSeries"
AutomationProperties.AutomationId="TestBtn"
CommandParameter="{Binding ViewerState}" Margin="0,1,0,0" Height="56">
<toolkit:LabelledButton.Content>
<Rectangle Fill="{DynamicResource Icon_Test}" Margin="0,2,0,-5"/>
</toolkit:LabelledButton.Content>
<toolkit:LabelledButton.Style>
<Style TargetType="{x:Type toolkit:LabelledButton}" BasedOn="{StaticResource {x:Type toolkit:LabelledButton}}">
<Setter Property="LabelText" Value="{Binding SelectedImageSeries, Mode=TwoWay}" />
<Setter Property="ToolTip" Value="{Binding SelectedImageSeries, Mode=TwoWay}" />
</Style>
</toolkit:LabelledButton.Style>
</toolkit:LabelledButton>
</xctk:SplitButton.Content>
<xctk:SplitButton.Style>
<Style TargetType="{x:Type xctk:SplitButton}" BasedOn="{StaticResource TestSplitButtonStyle}">
<Setter Property="Visibility" Value="Visible"/>
</Style>
</xctk:SplitButton.Style>
</xctk:SplitButton>

此外,当我单击该按钮时,它会执行关联的命令,但下拉菜单不会关闭。

您还必须将ListBox.SelectedItem属性绑定到SelectedImageSeries

看起来您使用SplitButton太复杂了。我发布了一个简化的解决方案。 由于我们现在已正确绑定SelectedImageSeriesListBox,因此无需在ListBoxItemDataTemplate中添加Button
您可以直接在属性资源库中处理选定的项,而不是执行TestCommand。为此,我在视图模型中添加了一个方法OnSelectedImageSeriesChanged

也不需要在SplitButton.Content中添加另一个嵌套的按钮(LabelButton(。您可以通过为SplitButton.ContentTemplate分配DataTemplate来修改内容布局,并将ICommand绑定到SplitButton.Command属性,并选择性地使用SplitButton.CommandParameter

仅当您将数据发送回数据源时,才需要BindingMode.TwoWay。在你使用它的每个地方都是多余的:LabelTextToolTip永远不会发送数据(他们不能(。大多数可以在反映用户输入时发送数据的属性默认是绑定TwoWay的,例如TextBox.TextListBox.SelectedItemToggleButton.IsChecked等。

查看模型

class MainViewModel
{
public ObservableCollection<ImageSeries> DropDownContentCollection { get; }
private ImageSeries selectedImageSeries;   
public ImageSeries SelectedImageSeries
{
get => this.selectedImageSeries;
set 
{ 
this.selectedImageSeries = value; 
OnPropertyChanged();
// Handle ListBox item selected. Replaces command.
OnSelectedImageSeriesChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

拆分按钮

<xctk:SplitButton Width="100" 
Content="{Binding SelectedImageSeries}"
Command="{Binding HandleButtonPressedCommand}"
CommandParameter="{Binding ViewerState}">
<xctk:SplitButton.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}" />
<Rectangle Fill="{DynamicResource Icon_Test}" Width="20" Height="20" />
</StackPanel>
</DataTemplate>
</xctk:SplitButton.ContentTemplate>
<xctk:SplitButton.DropDownContent>
<ListBox ItemsSource="{Binding DropDownContentCollection}" SelectedItem="{Binding SelectedImageSeries}" />
</xctk:SplitButton.DropDownContent>
</xctk:SplitButton>

最新更新