在初学写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
//我们不仅是为了显示实体,我们也要获取显示选中项的某一个值
}
}
}
与其用事件, 你还不如用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;
}
}
}
集合绑定之后,会传递到每个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就可以自动变名称了,而且错误可以在编辑时就抛出来,而不是运行时你到处去找问题。
以上供尔参考学习~