【问题标题】:2 Dimensional Dynamic Listview With Textbox带文本框的二维动态列表视图
【发布时间】:2012-08-08 10:05:45
【问题描述】:

这是一个带有动态标题和行的动态列表视图。但这里的问题是我尝试使用文本框作为

 xaml = "<DataTemplate><TextBox VerticalAlignment=\"Center\" TextChanged=\"{Binding " + propName + "}\" > " + propName + "</TextBox></DataTemplate>";

在 CreateDataTemplate 方法中不是带有绑定的复选框,而是在单击 btn 后无法提取值。

这里是 CheckBox 的代码。所以任何人都可以帮助我。我还需要文本框内的值。提前谢谢你

<Window x:Class="WpfListView.SalesPerson_SalesRegion_Association"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SalesPerson_SalesRegion_Association" Height="500" Width="500">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
    </Grid.RowDefinitions>
    <ListView Name="listView1" Width="400" Height="300" Margin="20" HorizontalAlignment="Left">
        <ListView.View>
            <GridView></GridView>
        </ListView.View>
    </ListView>

    <Button Grid.Row="1" HorizontalAlignment="Left" 
            Content="ShowSelectedMapping"
            Name="btnShow" Width="150" Margin="0,10,0,0" Click="btnShow_Click"></Button>

    <TextBlock Name="textBlock1" Grid.Row="2" 
                HorizontalAlignment="Left" Margin="0,10,0,0"></TextBlock>
</Grid>

 public partial class SalesPerson_SalesRegion_Association : Window
{
    public SalesPerson_SalesRegion_Association()
    {
        InitializeComponent();
        AddColumnsToListView();
        DataTable dt = DataHelper.GetRegionPersonAssociation();
        listView1.ItemsSource = dt.DefaultView;
    }

    private void btnShow_Click(object sender, RoutedEventArgs e)
    {
        DataView view = listView1.ItemsSource as DataView;
        DataTable userSelectionTbl = view.ToTable();

        DataTable idTable = DataHelper.GetRegionIdPersonIdMatrix();
        List<SalesRegion> lstRegion = SalesRegion.GetRegions();

        string selectedRegion = string.Empty;
        string msg = string.Empty;
        DataRow dRow=null;

        int totRows = userSelectionTbl.Rows.Count;
        int totCols = lstRegion.Count-1;
        string strTempMsg = string.Empty;
        bool isColChecked = false;
        for (int rowIndex = 0; rowIndex < totRows; rowIndex++)
        {
            dRow = userSelectionTbl.Rows[rowIndex];
            strTempMsg = dRow[0].ToString() + "(" + idTable.Rows[rowIndex][0].ToString() + ")" +  " : ";

            string rgnId="";
            isColChecked = false;
            foreach (SalesRegion region in lstRegion)
            {
                if (((bool)dRow[region.RegionName]) == true)
                {
                    rgnId = idTable.Rows[rowIndex][region.RegionName].ToString();
                    strTempMsg += region.RegionName + "(" + rgnId + ")";
                    isColChecked = true;                    }
            }
            if (isColChecked == false)
            {
                strTempMsg += "  : No region selected";
            }
            strTempMsg += Environment.NewLine;

            msg += strTempMsg;
        }

        textBlock1.Text = msg;
        string tt = "t";
    }
    private void AddColumnsToListView()
    {
        List<SalesRegion> lstSalesRegion = SalesRegion.GetRegions();
        List<SalesPerson> lstSalesPerson = SalesPerson.GetSalesPersons();

        GridViewColumn colSalesPerson = new GridViewColumn();
        colSalesPerson.Header = "Sales Person";
        colSalesPerson.DisplayMemberBinding = new Binding("SalesPersonName");
        colSalesPerson.Width = 150;
        GridView grdView = listView1.View as GridView;
        grdView.Columns.Add(colSalesPerson);

        //Since columns are dynamic we need a data template per column
        // in which we bind the checkBox's checked property with 
        //appropriate columnName
        Dictionary<string, DataTemplate> dict = GetDataTemplates(lstSalesRegion);

        foreach (SalesRegion region in lstSalesRegion)
        {
            GridViewColumn col1 = new GridViewColumn();
            col1.Header = region.RegionName;
            DataTemplate dTempl = dict[region.RegionName];
            col1.CellTemplate = dTempl;
            grdView.Columns.Add(col1);
        }
    }

    private Dictionary<string, DataTemplate> GetDataTemplates(List<SalesRegion> lstSalesRegion)
    {
        Dictionary<string, DataTemplate> dict = new Dictionary<string, DataTemplate>();
        foreach (SalesRegion region in lstSalesRegion)
        {
            DataTemplate dTemplate = CreateDataTemplate(region.RegionName);
            dict.Add(region.RegionName, dTemplate);
        }
        return dict;
    }
    private DataTemplate CreateDataTemplate(string propName)
    {
        MemoryStream sr = null;
        ParserContext pc = null;
        string xaml = string.Empty;
        xaml = "<DataTemplate><CheckBox VerticalAlignment=\"Center\" IsChecked=\"{Binding " + propName + "}\"></CheckBox></DataTemplate>";
        sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));
        pc = new ParserContext();
        pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
        pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
        DataTemplate datatemplate = (DataTemplate)XamlReader.Load(sr, pc);
        return datatemplate;
    }

} // class ends here

} // DataHelper 类

public class SalesPerson
{
    public int SalesPersonId
    { get; set; }
    public string SalesPersonName
    { get; set; }

    public SalesPerson(int salesPersonId, string salesPersonName)
    {
        this.SalesPersonId = salesPersonId;
        this.SalesPersonName = salesPersonName;
    }

    public static List<SalesPerson> GetSalesPersons()
    {
        List<SalesPerson> lst = new List<SalesPerson>();
        lst.Add(new SalesPerson(101, "SalesPerson1"));
        lst.Add(new SalesPerson(201, "SalesPerson2"));
        lst.Add(new SalesPerson(301, "SalesPerson3"));
        lst.Add(new SalesPerson(401, "SalesPerson4"));
        lst.Add(new SalesPerson(501, "SalesPerson5"));
        return lst;
    }
} // class SalesPerson ends here

public class SalesRegion
{
    public int RegionId
    { get; set; }
    public string RegionName
    { get; set; }

    public SalesRegion(int regionId, string regionName)
    {
        this.RegionId = regionId;
        this.RegionName = regionName;
    }
    public static List<SalesRegion> GetRegions()
    {
        List<SalesRegion> lst = new List<SalesRegion>();
        lst.Add(new SalesRegion(501,"North"));
        lst.Add(new SalesRegion(502, "South"));
        lst.Add(new SalesRegion(503, "East"));
        lst.Add(new SalesRegion(504, "West"));
        lst.Add(new SalesRegion(505, "MyRegion"));
        return lst;
    }
} // class SalesRegion ends here

public class DataHelper
{
    public static DataTable GetRegionPersonAssociation()
    {
        DataTable dt = new DataTable();

        //Create data table structure
        // SalesPerson   Region1   Region2   Region3 ....
        DataColumn colSalesPerson = new DataColumn("SalesPersonName", typeof(string));
        dt.Columns.Add(colSalesPerson);

        List<SalesRegion> lstRegions = SalesRegion.GetRegions();
        DataColumn colRegion = null;
        foreach (SalesRegion region in lstRegions)
        {
            colRegion = new DataColumn(region.RegionName, typeof(bool));
            dt.Columns.Add(colRegion);
        }
        //Fill data into the data table
        List<SalesPerson> personList = SalesPerson.GetSalesPersons();
        DataRow dRow = null;
        foreach (SalesPerson sp in personList)
        {
            dRow = dt.NewRow();
            dRow["SalesPersonName"] = sp.SalesPersonName;
            foreach (SalesRegion sr in lstRegions)
            {
                dRow[sr.RegionName] = false;
            }
            dt.Rows.Add(dRow);
        }
        return dt;
    }

    public static DataTable GetRegionIdPersonIdMatrix()
    {
        DataTable dt = new DataTable();

        //Create data table structure
        // SalesPerson   Region1   Region2   Region3 ....
        DataColumn colSalesPerson = new DataColumn("SalesPersonId", typeof(int));
        dt.Columns.Add(colSalesPerson);

        List<SalesRegion> lstRegions = SalesRegion.GetRegions();
        DataColumn colRegion = null;
        foreach (SalesRegion region in lstRegions)
        {
            colRegion = new DataColumn(region.RegionName, typeof(int));
            dt.Columns.Add(colRegion);
        }
        //Fill data into the data table
        List<SalesPerson> personList = SalesPerson.GetSalesPersons();
        DataRow dRow = null;
        foreach (SalesPerson sp in personList)
        {
            dRow = dt.NewRow();
            dRow["SalesPersonId"] = sp.SalesPersonId;
            foreach (SalesRegion sr in lstRegions)
            {
                dRow[sr.RegionName] = sr.RegionId;
            }
            dt.Rows.Add(dRow);
        }
        return dt;
    }    } // class DataHelper ends here

【问题讨论】:

  • 小心:您使用 TextChanged=\"{Binding " + propName + "} 将属性绑定到事件
  • 那么我该如何处理呢?最后,点击按钮时,我需要显示文本框的值以及水输出。
  • 您是否需要文本框,因为您希望用户能够编辑区域名称?无论如何,我建议你看看 ObservableCollection 类
  • 是的。我想将值绑定到文本框,当一个事件与复选框类似时引发,但这不是文本框发生的。那你能帮帮我吗?
  • 我运行了您的代码:这 IsChecked=\"{Binding " + propName + "}\" 没有意义,因为您将字符串值绑定到 bool 属性。我了解您的用户体验的用途,但我不明白您为什么要使用文本框而不是复选框!

标签: wpf wpf-controls wpfdatagrid


【解决方案1】:

使用这样的文本框数据模板

xaml = "<DataTemplate><TextBox VerticalAlignment=\"Center\" Tag=\"{Binding " + propName + ", Mode=TwoWay}\" > " + propName + "</TextBox></DataTemplate>";

为您的 listview.resources 添加文本框样式

            <Style TargetType="{x:Type TextBox}">
                <EventSetter Event="TextChanged" Handler="TextBox_TextChanged"></EventSetter>
            </Style>

将处理程序添加到您的代码隐藏

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        (sender as TextBox).Tag = true;
    }

这将像您的复选框示例一样。

【讨论】:

  • 非常感谢。非常感谢您的帮助。我对此还有一个问题。如何从已编辑的文本框中获取值。
  • 您需要升级绑定到每个单元格的对象。不是简单的布尔值,而是像 bool | 这样的结构字符串,因此您可以将布尔值绑定到文本框的 Tag 属性,并将字符串绑定到 Text 属性(请考虑将答案标记为已接受)
  • 很抱歉打扰你,米歇尔,但我知道答案。你真的很高兴能帮忙。再次感谢您。
  • 嘿,米歇尔,我只是想知道如何将数据库中的行中的值添加到文本框中。
  • xaml = "";
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多