首页 新闻 会员 周边 捐助

WPF ListBox 模板列点击事件,获取其中一个值

0
悬赏园豆:30 [已解决问题] 解决于 2019-08-23 09:54

在初学写WPF例程的时候 模板列的点击事件,只能获取点击事件,但无法获取模板列的某一个TextBlock的值
我只是想要在点击事件的时候获取某一个值

比如说我有这样几条数据
第一个名字:陈真
第二个名字:陈小真
类型:None

第一个名字:诺克萨斯
第二个名字:诺克萨斯之手
类型:Processing

第一个名字:黑色玫瑰
第二个名字:黑色玫瑰风暴
类型:Progress

第一个名字:祖安
第二个名字:祖安狂人
类型:Menaduo

如何在点击的时候获取陈真这个值

下面贴出代码,在线等大佬帮忙... 不胜感激

<Window x:Class="Wpf_Demo_Test.常用控件绑定以及获取基本值"
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:Wpf_Demo_Test"
mc:Ignorable="d"
Title="常用控件绑定以及获取基本值" Height="300" Width="300">
<Window.Resources>
<DataTemplate x:Key="listBoxTemplate">
<StackPanel Margin="4">
<DockPanel>
<TextBlock FontWeight="Bold" Text="第一个名字:" DockPanel.Dock="Left" Margin="5,0,10,0"/>
<TextBlock Text=" "/>
<TextBlock Text="{Binding FirstName}" x:Name="FirstName" Foreground="Green" FontWeight="Bold"/>
</DockPanel>
<DockPanel>
<TextBlock FontWeight="Bold" Text="第二个名字:" DockPanel.Dock="Left" Margin="5,0,5,0"/>
<TextBlock Text=" "/>
<TextBlock Text="{Binding LastName}" x:Name="LastName" Foreground="DarkOrange"/>
</DockPanel>
<DockPanel>
<TextBlock FontWeight="Bold" Text="类型:" DockPanel.Dock="Left" Margin="5,0,5,0"/>
<TextBlock Text=" "/>
<TextBlock Text="{Binding Enmu}" x:Name="Enmu" Foreground="Cyan"/>
</DockPanel>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<!--绑定数据集合中返回的第一张表-->
<ListBox Margin="17,8,15,26" Name="listBox1" ItemsSource="{Binding Tables[0]}"
ItemTemplate="{StaticResource listBoxTemplate}" SelectionChanged="listBox1_SelectionChanged"/>
</Grid>
</Window>

后台数据绑定,

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
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 Wpf_Demo_Test
{
/// <summary>
/// 常用控件绑定以及获取基本值.xaml 的交互逻辑
/// </summary>
public partial class 常用控件绑定以及获取基本值 : Window
{
public 常用控件绑定以及获取基本值()
{
InitializeComponent();
BindData();
}

    string sql = "select FirstName,LastName,Enmu from Customer";
    string connectionString = "Data Source =.; Initial Catalog = customertest; Integrated Security = True";
    /// <summary>
    /// 页面加载时绑定数据的方法
    /// </summary>
    private void BindData()
    {
        DataSet ds = new DataSet();
        using (SqlConnection sqlcn = new SqlConnection(connectionString))
        {
            using (SqlCommand cmd = new SqlCommand(sql, sqlcn))
            {
                SqlDataAdapter adapter = new SqlDataAdapter();
                sqlcn.Open();
                adapter.SelectCommand = cmd;
                adapter.Fill(ds, "province");
                listBox1.DataContext = ds;
            }
        }
    }


    //listbox下拉选中事件
    private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        //object s1 = listBox1.SelectedValue;
        MessageBox.Show("我们选中了这个选项");          //System.Data.DataRowView
        //我们不仅是为了显示实体,我们也要获取显示选中项的某一个值
    }



}

}

爱诚的主页 爱诚 | 初学一级 | 园豆:175
提问于:2019-08-15 19:29
< >
分享
最佳答案
0

与其用事件, 你还不如用winform去,这样没有发挥出WPF的优势,WFP的MVVM模式很牛逼的,随便一本介绍WPF的书都会提到,不要用事件,用双向绑定。

<Window x:Class="WPFTest.MainWindow"
        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:WPFTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <ListBox ItemsSource="{Binding People}" SelectedItem="{Binding SelectedPerson}"></ListBox>
    </Grid>
</Window>
using System.Windows;

namespace WPFTest
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new ViewModel();
        }
    }
}
using System.Collections.Generic;
using System.Windows;

namespace WPFTest
{
    class ViewModel
    {
        public ViewModel()
        {
            People = new List<Person> {
                new Person { Name1 = "陈真", Name2 = "陈小真" },
                new Person { Name1 = "诺克萨斯", Name2 = "诺克萨斯之手" },
                new Person { Name1 = "黑色玫瑰", Name2 = "黑色玫瑰风暴" },
            };
        }
        public List<Person> People { get; set; }

        private Person _selectedPerson;

        public Person SelectedPerson
        {
            get { return _selectedPerson; }
            set
            {
                _selectedPerson = value;
                MessageBox.Show(value.ToString());
            }
        }
    }

    class Person
    {
        public string Name1 { get; set; }

        public string Name2 { get; set; }

        public override string ToString()
        {
            return Name1 + "-" + Name2;
        }
    }
}
收获园豆:30
会长 | 专家六级 |园豆:12463 | 2019-08-16 09:16
其他回答(1)
1

集合绑定之后,会传递到每个Item的DataContext上,因此肯定可以拿到~~~

模版虽然方便,但介于对于新手对面向对象的理解、重用等等就不是太友好,以及你的class属性改变的时候,无法智能化跟随自动变化。很多时候不推荐完全去用xmal方式。

我这里有个不常用的方式(如果你有所了解视图实现模式那么就是很简单)

    public partial class ListBoxEx
    {
        public Func<ListBoxEx, UIElement> OnGenerateItem;
        public int GenerateCounterOnStart { get; private set; }
        public Action<ListBoxEx,DependencyPropertyChangedEventArgs> PropertyChanged { get; set; }
        public ListBoxEx()
        {
            InitializeComponent();
        }

        protected override DependencyObject GetContainerForItemOverride()
        {
            GenerateCounterOnStart++;
            var itemContent = OnGenerateItem?.Invoke(this);
            return itemContent ?? new ListBoxItem(); ;
        }

        public ScrollViewerEx ScrollViewer { get; private set; }
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            ScrollViewer = this.GetTemplateChild("_cScrollViewer") as ScrollViewerEx;
        }

        public new IEnumerable ItemsSource
        {
            get => base.ItemsSource;
            set
            {
                base.ItemsSource = value;
                GenerateCounterOnStart = 0;
            }
        }

        public int MaxItemsCount { get; set; } = 1000;
        public bool IsReduceHead { get; set; }
        protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
        {
            base.OnItemsChanged(e);
            while (MaxItemsCount > 0 && Items.Count > MaxItemsCount)
            {
                if (!IsReduceHead)
                {
                    var item = Items[Items.Count - 1];
                    if(item is DependencyObject) item.ToType<DependencyObject>().GetAllChildren().OfType<Image>().ToList().ForEach(t=>t.Source = null);
                    Items.RemoveAt(Items.Count - 1);
                }
                else
                {
                    var item = Items[0];
                    if (item is DependencyObject) item.ToType<DependencyObject>().GetAllChildren().OfType<Image>().ToList().ForEach(t => t.Source = null);
                    Items.RemoveAt(0);
                }
            }
        }

        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e);
            PropertyChanged?.Invoke(this,e);
        }

        protected override AutomationPeer OnCreateAutomationPeer()
        {
            return new ControlSpecificCustomAutomationPeer(this);
        }
    }

对于ListBox.Items你是可以随便插入显示(包括string)对象实例的,要做到这个你还可以不用模版方法(如果Item控件显示你可以绑定也可以不绑定,绑定的话就要在ListBoxEx中传递自行写)。

如:(这是ListBoxEx实例)_cListBox进入.OnGenerateItem = OnGenerateItem;

(WPF中ListBox中Items的控件很有意思,你可以自己Items.Add试试,然后看看源码,用源码中的控件你再试试,写得挺复杂的)

如果绑定不用模版怎么写,当然是代码了:

_c次数.SetBinding(IntegerUpDown.ValueProperty, ClassEx.GetPropertyName<霸屏踢人>(t => t.每分钟极限次数));

这样你在改变"每分钟极限次数"这个属性的时候,Vs就可以自动变名称了,而且错误可以在编辑时就抛出来,而不是运行时你到处去找问题。

以上供尔参考学习~

花飘水流兮 | 园豆:13615 (专家六级) | 2019-08-17 15:18
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册