使用自定义对象

时间:2016-06-06 17:38:12

标签: c# wpf listview listviewitem

我已搜索,搜索和搜索但无法找到答案。

C#和WPF,我有一个包含5列的ListView,每列都有一个TextBox。

我的自定义课程

public class SomeThing
{
    public String field1 { get; set; }
    public String field2 { get; set; }
    public String field3 { get; set; }
    public String field4 { get; set; }
    public String field5 { get; set; }
}

我的添加代码

SomeThing item = new SomeThing();
lstItems.Items.Add(item);

我的keydown代码

private void TextBox_KeyDown(object sender, KeyEventArgs e)
    {
        if(e.Key == Key.Return || e.Key == Key.Tab)
        {
            TextBox tb = (TextBox)sender;
            Grid grid = (Grid)tb.Parent;                

            if (tb.Tag.Equals("Price"))
            {
                if(lstItems.Items.Count <= lstItems.SelectedIndex + 1) {                     
                    SomeThing item = new SomeThing();
                    lstItems.Items.Add(item);                        
                }

                lstItems.SelectedIndex = lstItems.SelectedIndex + 1;                   

                ListViewItem selectedItem = (ListViewItem)lstItems.ItemContainerGenerator.ContainerFromItem(this.lstItems.SelectedItem);

                    e.Handled = true;
            }                               

        }
    }

但是

ListViewItem selectedItem = (ListViewItem)lstItems.ItemContainerGenerator.ContainerFromItem(this.lstItems.SelectedItem);

始终为null,

this.lstItems.SelectedItem 

只是实例的对象&#34; SomeThing&#34;。

如何获取ListView容器?

如何将TextBox聚焦在新选定的行上?

请帮忙

1 个答案:

答案 0 :(得分:0)

您可能正在尝试从ItemContainerGenerator获取尚未生成的内容。将项添加到ItemsControlListView是其子类)不会立即为该项创建容器。涉及延迟。

这不是处理ItemsControl实例的理想方式。它们实际上是围绕与MVVM设计模式一起使用而设计的。但是,如果您出于某种原因需要以这种方式使用它,那么您需要注意Status上的ItemContainerGenerator属性以及相关的StatusChanged事件。

所以,沿着这些方向:

    if (myItemsControlInstance.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
    {
        // You should be able to get the container using ContainerFromItem
    }
    else
    {
        // You will have to wait
        myItemsControlInstance.ItemContainerGenerator.StatusChanged += myItemsControlInstance_StatusChanged;
    }

...

void myItemsControlInstance_StatusChanged(object sender, EventArgs e)
{
    if (myItemsControlInstance.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
    {
        myItemsControlInstance.ItemContainerGenerator.StatusChanged -= myEventHandler;
        // You should be able to get the container now using ContainerFromItem.
        // However, layout hasn't been performed on it yet at this point, so there is
        // no guarantee that the item is in good condition to be messed with yet.
        LayoutUpdated += app_LayoutUpdated;
    }
}

void app_LayoutUpdated(object sender, EventArgs e)
{
    LayoutUpdated -= app_LayoutUpdated;
    if (myItemsControlInstance.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
    {
        // Now, you can finally get the container using ContainerFromItem and do something with it.
    }
    else
    {
        // It looks like more items needed to be generated...
        myItemsControlInstance.ItemContainerGenerator.StatusChanged += myItemsControlInstance_StatusChanged;
    }
}

除了直接使用ItemContainerGenerator之外,还有一些事情需要注意:

  • 生成器上的Status可以是Error。你可能想检查一下,虽然我从未见过它。
  • 如果ItemsControl正在使用虚拟化面板来包含项目,则可能是您尝试访问不在视图中的项目,因此不存在。您可以通过设置ItemsPanel属性来覆盖用于不虚拟化的面板类型,例如StackPanel而不是VirtualizingStackPanel,或者您可以确保项目以某种方式滚动到视图中启动流程(这是一个完全独立的主题)。

我的建议是切换到MVVM模型,并以更自然的方式阅读如何使用ItemsControl,因为这样做很复杂且容易出错。