对齐模板化的ComboBox并将当前项传递给有界命令 [英] Align templated ComboBox and pass current item to the bounded Command

查看:53
本文介绍了对齐模板化的ComboBox并将当前项传递给有界命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在WPF ComboBox中实现动态删除项目。实施时遇到一些问题。  Xaml在下面。


  1. 如何将红色X图像对齐ComboBox区域的右侧? Horizo​​ntalContentAlignment没有帮助。
  2. 点击X图像被绑定到DeleteEntityCommand被调用好了,但是如何传递用户想要删除的项?它不是SelectedItem,它是一个用鼠标突出显示的项目。
  3. 当折叠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"的Horizo​​ntalAlignment = 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区域的右侧? Horizo​​ntalContentAlignment没有帮助。


不要将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 Horizo​​ntalAlignment =" 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"的Horizo​​ntalAlignment = 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.

  1. How do I align red X images to the right of the ComboBox area? HorizontalContentAlignment doesn't help.
  2. 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.
  3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆