对齐模板化的ComboBox并将当前项传递给有界命令 [英] Align templated ComboBox and pass current item to the bounded Command
问题描述
我需要在WPF ComboBox中实现动态删除项目。实施时遇到一些问题。 Xaml在下面。
- 如何将红色X图像对齐ComboBox区域的右侧? HorizontalContentAlignment没有帮助。
- 点击X图像被绑定到DeleteEntityCommand被调用好了,但是如何传递用户想要删除的项?它不是SelectedItem,它是一个用鼠标突出显示的项目。
- 当折叠ComboBox时,不应该为当前的SelectedItem显示红色十字按钮。
XAML:
< ComboBox ItemsSource =" {Binding EntitiesData}"
SelectedItem =" {Binding SelectedEntity}" >
< ComboBox.ItemTemplate>
< DataTemplate>
< Grid>
< Grid.ColumnDefinitions>
< ColumnDefinition Width =" Auto" />
< ColumnDefinition Width =" 20" />
< /Grid.ColumnDefinitions>
< TextBlock Grid.IsSharedSizeScope =" True" Text =" {Binding EntityName,Mode = OneWay}"余量= QUOT; 5,0" />
< Image Grid.Column =" 1"源= QUOT; .. \Resources\DeleteIcon.png"的HorizontalAlignment = QUOT;中心" >
< Image.InputBindings>
< MouseBinding Gesture =" LeftClick"
Command =" {Binding DataContext.DeleteEntityCommand,
RelativeSource = {RelativeSource FindAncestor,AncestorType = {x:Type Window}}}"
CommandParameter ="" />
< /Image.InputBindings>
< / Image>
< / Grid>
< / DataTemplate>
< /ComboBox.ItemTemplate>
< / ComboBox>
$
您好IgorT75,
>>如何将红色X图像对齐ComboBox区域的右侧? HorizontalContentAlignment没有帮助。
不要将ColumnDefinition的宽度设置为auto,将其设置为固定值,您可以通过max设置值项目长度。
>> 点击X图像被绑定到DeleteEntityCommand,调用Ok,但是如何传递用户想要删除的项目?它不是SelectedItem,它是由鼠标突出显示的项目。
您可以将文本块的文本作为 CommandParameter传递。
>> <当折叠ComboBox时,不应为当前的SelectedItem显示strong> 红色十字按钮。
在您的实体模型中添加名为ISSHow的属性,然后绑定到您的XAML。这里有完整的示例代码供您参考。
#XAML
< Window x:Class =" WpfApp1。 Comobox.Window2"
xmlns =" http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x =" http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d =" http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc =" http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local =" clr-namespace:WpfApp1.Comobox"
mc:Ignorable =" d"
Title =" Window2"高度= QUOT; 450"宽度= QUOT; 800">
< Grid>
< StackPanel>
< ComboBox Margin =" 20,50,20,20" X:名称= QUOT; combobox1"宽度= QUOT; 220" ItemsSource =" {Binding EntitiesData}" SelectedItem =" {Binding SelectedEntity}" >
< ComboBox.ItemTemplate>
< DataTemplate>
< Grid HorizontalAlignment =" Stretch">
< Grid.ColumnDefinitions>
< ColumnDefinition Width =" {Binding RelativeSource = {RelativeSource FindAncestor,AncestorType = {x:Type Window}},Path = DataContext.MaxWidth}" />
< ColumnDefinition Width =" 20" />
< /Grid.ColumnDefinitions>
< TextBlock Grid.IsSharedSizeScope =" True" X:名称= QUOT;实体名称" Text =" {Binding EntityName,Mode = OneWay}"余量= QUOT; 5,0" />
< Image Visibility =" {Binding ISShow}" Grid.Column = QUOT 1 QUOT;源= QUOT; d:\Project\WPF\WpfApp\WpfApp1\Resources\StatusOffline_stop_48x.png"的HorizontalAlignment = QUOT;中心" >
< Image.InputBindings>
< MouseBinding Gesture =" LeftClick"
Command =" {Binding DataContext.DeleteEntityCommand,
RelativeSource = {RelativeSource FindAncestor,AncestorType = {x:Type Window}}}"
CommandParameter =" {Binding Path = Text,ElementName = EntityName}" />
< /Image.InputBindings>
< / Image>
< / Grid>
< / DataTemplate>
< /ComboBox.ItemTemplate>
< / ComboBox>
< / StackPanel>
< / Grid>
< / Window>
#Code Behind
使用System;
使用System.Collections.Generic;使用System.ComponentModel
;
使用System.Linq;
使用System.Text;
使用System.Threading.Tasks;使用System.Windows
;使用System.Windows.Controls
;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Shapes;
名称空间WpfApp1.Comobox
{
///< summary>
/// Window2.xaml的互动逻辑
///< / summary>
public partial class Window2:Window
{
public Window2()
{
InitializeComponent();
this.DataContext = new ConnectionViewModel();
}
}
公共类PhoneBookEntry
{
public string EntityName {get;组; }
public string ISShow {get;组; }
public PhoneBookEntry(string name,string show)
{
EntityName = name;
ISShow = show;
}
公共覆盖字符串ToString()
{
返回EntityName;
}
}
公共类ConnectionViewModel:INotifyPropertyChanged
{
public ConnectionViewModel()
{
IList< PhoneBookEntry> list = new List< PhoneBookEntry>();
list.Add(new PhoneBookEntry(" Line1"," Visible"));
list.Add(new PhoneBookEntry(" Line2"," Visible"));
list.Add(new PhoneBookEntry(" Line3"," Visible"));
list.Add(new PhoneBookEntry(" SomethingwhatlongLine4"," Visible"));
list.Add(new PhoneBookEntry(" Line5"," Visible"));
list.Add(new PhoneBookEntry(" extra long line is here"," Visible"));
list.Add(new PhoneBookEntry(" Line7"," Visible"));
_phonebookEntries = new CollectionView(list);
var maxlength = list.OrderByDescending(t => t.EntityName.Length).Select(t => t.EntityName.Length).First();
_showwidth = maxlength * 7;
}
ICommand deleteEntityCommand;
public ICommand DeleteEntityCommand
{
get {return deleteEntityCommand ?? (deleteEntityCommand = new RelayCommand(DeleteEntity)); }
}
private void DeleteEntity(object obj)
{
string test = obj.ToString();
//抛出新的NotImplementedException();
}
private readonly CollectionView _phonebookEntries;
private PhoneBookEntry _phonebookEntry;
private double _showwidth;
public CollectionView EntitiesData
{
get {return _phonebookEntries; }
}
public double MaxWidth
{
get {return _showwidth; }
设置
{
if(_showwidth == value)return;
_showwidth = value;
OnPropertyChanged(" MaxWidth");
}
}
public PhoneBookEntry SelectedEntity
{
get {return _phonebookEntry; }
设置
{
if(_phonebookEntry == value)return;
_phonebookEntry = value;
_phonebookEntry.ISShow =" Hidden" ;;
OnPropertyChanged(" SelectedEntity");
}
}
private void OnPropertyChanged(string propertyName)
{
if(PropertyChanged!= null)
PropertyChanged(this,new PropertyChangedEventArgs(propertyName的));
}
公共事件PropertyChangedEventHandler PropertyChanged;
}
}
祝你好运,
张龙
I need to implement dynamic deletion of items in WPF ComboBox. Got some problems with the implementation. Xaml is below.
- How do I align red X images to the right of the ComboBox area? HorizontalContentAlignment doesn't help.
- Click on X image is bounded to DeleteEntityCommand which is invoked Ok, but how do I pass item which user wants to delete? It's not a SelectedItem, it's an item highlighted by mouse.
- Red cross button should not be displayed for a current SelectedItem when ComboBox is folded.
XAML:
<ComboBox ItemsSource="{Binding EntitiesData}" SelectedItem="{Binding SelectedEntity}" > <ComboBox.ItemTemplate> <DataTemplate> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="20" /> </Grid.ColumnDefinitions> <TextBlock Grid.IsSharedSizeScope="True" Text="{Binding EntityName, Mode=OneWay}" Margin="5,0" /> <Image Grid.Column="1" Source="..\Resources\DeleteIcon.png" HorizontalAlignment="Center" > <Image.InputBindings> <MouseBinding Gesture="LeftClick" Command="{Binding DataContext.DeleteEntityCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" CommandParameter=""/> </Image.InputBindings> </Image> </Grid> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox>
Hi IgorT75,
>>How do I align red X images to the right of the ComboBox area? HorizontalContentAlignment doesn't help.
Don't set ColumnDefinition's width with value auto, set it as a fixed value, you could set the value through the max length of item.
>>Click on X image is bounded to DeleteEntityCommand which is invoked Ok, but how do I pass item which user wants to delete? It's not a SelectedItem, it's an item highlighted by mouse.
You could pass the textblock's text as CommandParameter.
>>Red cross button should not be displayed for a current SelectedItem when ComboBox is folded.
Add a property named ISSHow in your Entity model, then binding to your XAML. and here is complete sample code for your reference.
#XAML
<Window x:Class="WpfApp1.Comobox.Window2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp1.Comobox" mc:Ignorable="d" Title="Window2" Height="450" Width="800"> <Grid> <StackPanel> <ComboBox Margin="20,50,20,20" x:Name="combobox1" Width="220" ItemsSource="{Binding EntitiesData}" SelectedItem="{Binding SelectedEntity}" > <ComboBox.ItemTemplate> <DataTemplate> <Grid HorizontalAlignment="Stretch"> <Grid.ColumnDefinitions> <ColumnDefinition Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.MaxWidth}"/> <ColumnDefinition Width="20" /> </Grid.ColumnDefinitions> <TextBlock Grid.IsSharedSizeScope="True" x:Name="EntityName" Text="{Binding EntityName, Mode=OneWay}" Margin="5,0" /> <Image Visibility="{Binding ISShow}" Grid.Column="1" Source="D:\Project\WPF\WpfApp\WpfApp1\Resources\StatusOffline_stop_48x.png" HorizontalAlignment="Center" > <Image.InputBindings> <MouseBinding Gesture="LeftClick" Command="{Binding DataContext.DeleteEntityCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" CommandParameter="{Binding Path=Text, ElementName=EntityName}"/> </Image.InputBindings> </Image> </Grid> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> </StackPanel> </Grid> </Window>#Code Behind
using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace WpfApp1.Comobox { /// <summary> /// Interaction logic for Window2.xaml /// </summary> public partial class Window2 : Window { public Window2() { InitializeComponent(); this.DataContext = new ConnectionViewModel(); } } public class PhoneBookEntry { public string EntityName { get; set; } public string ISShow { get; set; } public PhoneBookEntry(string name, string show) { EntityName = name; ISShow = show; } public override string ToString() { return EntityName; } } public class ConnectionViewModel : INotifyPropertyChanged { public ConnectionViewModel() { IList<PhoneBookEntry> list = new List<PhoneBookEntry>(); list.Add(new PhoneBookEntry("Line1", "Visible")); list.Add(new PhoneBookEntry("Line2", "Visible")); list.Add(new PhoneBookEntry("Line3", "Visible")); list.Add(new PhoneBookEntry("SomethingwhatlongLine4", "Visible")); list.Add(new PhoneBookEntry("Line5", "Visible")); list.Add(new PhoneBookEntry("extra long line is here", "Visible")); list.Add(new PhoneBookEntry("Line7", "Visible")); _phonebookEntries = new CollectionView(list); var maxlength = list.OrderByDescending(t => t.EntityName.Length).Select(t => t.EntityName.Length).First(); _showwidth = maxlength * 7; } ICommand deleteEntityCommand; public ICommand DeleteEntityCommand { get { return deleteEntityCommand ?? (deleteEntityCommand = new RelayCommand(DeleteEntity)); } } private void DeleteEntity(object obj) { string test = obj.ToString(); //throw new NotImplementedException(); } private readonly CollectionView _phonebookEntries; private PhoneBookEntry _phonebookEntry; private double _showwidth; public CollectionView EntitiesData { get { return _phonebookEntries; } } public double MaxWidth { get { return _showwidth; } set { if (_showwidth == value) return; _showwidth = value; OnPropertyChanged("MaxWidth"); } } public PhoneBookEntry SelectedEntity { get { return _phonebookEntry; } set { if (_phonebookEntry == value) return; _phonebookEntry = value; _phonebookEntry.ISShow = "Hidden"; OnPropertyChanged("SelectedEntity"); } } private void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } public event PropertyChangedEventHandler PropertyChanged; } }Best regards,
Zhanglong
这篇关于对齐模板化的ComboBox并将当前项传递给有界命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!