44

ListBoxのようなコントロールに文字列を含める必要がないことにまだ気付いていない人のために、例を挙げています。彼は書式設定された文字列を保存し、複雑な解析フープを飛び越えてデータを元に戻していListBoxました。より良い方法があることを彼に示したいと思います。

オブジェクトを に格納してListBoxから に影響する値を更新すると、ToString自体ListBoxが更新されないことに気付きました。コントロールを呼び出してみましRefreshたが、どちらも機能しません。Update私が使用している例のコードは次のとおりです。リストボックスとボタンをフォームにドラッグする必要があります。

Public Class Form1

    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
        MyBase.OnLoad(e)

        For i As Integer = 1 To 3
            Dim tempInfo As New NumberInfo()
            tempInfo.Count = i
            tempInfo.Number = i * 100
            ListBox1.Items.Add(tempInfo)
        Next
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        For Each objItem As Object In ListBox1.Items
            Dim info As NumberInfo = DirectCast(objItem, NumberInfo)
            info.Count += 1
        Next
    End Sub
End Class

Public Class NumberInfo

    Public Count As Integer
    Public Number As Integer

    Public Overrides Function ToString() As String
        Return String.Format("{0}, {1}", Count, Number)
    End Function
End Class

おそらくフィールドの使用に問題があると思い、INotifyPropertyChangedを実装しようとしましたが、これは効果がありませんでした。(フィールドを使用している理由は、これが例であり、説明しているトピックとは関係のない数十行を追加したくないためです。)

正直なところ、このようにアイテムを更新しようとしたことはありません。以前は、アイテムを編集するのではなく、常にアイテムを追加/削除していました。そのため、この作業を行う方法がわからないことに気づいたことはありません。

それで、私は何が欠けていますか?

4

10 に答える 10

34

更新するリスト ボックスが必要な場合は、このクラスを使用します。

リスト内のオブジェクトを更新してから、インデックスが使用可能かどうかに応じて、含まれているメソッドのいずれかを呼び出します。リストに含まれているオブジェクトを更新しているが、インデックスがない場合は、RefreshItems を呼び出してすべての項目を更新する必要があります。

public class RefreshingListBox : ListBox
{
    public new void RefreshItem(int index)
    {
        base.RefreshItem(index);
    }

    public new void RefreshItems()
    {
        base.RefreshItems();
    }
}
于 2008-09-14T23:27:51.993 に答える
29
lstBox.Items[lstBox.SelectedIndex] = lstBox.SelectedItem;
于 2010-11-26T14:06:50.787 に答える
25

BindingList は、バインディングの更新を単独で処理します。

using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace TestBindingList
{
    public class Employee
    {
        public string Name { get; set; }
        public int Id { get; set; }
    }

    public partial class Form1 : Form
    {
        private BindingList<Employee> _employees;

        private ListBox lstEmployees;
        private TextBox txtId;
        private TextBox txtName;
        private Button btnRemove;

        public Form1()
        {
            InitializeComponent();

            FlowLayoutPanel layout = new FlowLayoutPanel();
            layout.Dock = DockStyle.Fill;
            Controls.Add(layout);

            lstEmployees = new ListBox();
            layout.Controls.Add(lstEmployees);

            txtId = new TextBox();
            layout.Controls.Add(txtId);

            txtName = new TextBox();
            layout.Controls.Add(txtName);

            btnRemove = new Button();
            btnRemove.Click += btnRemove_Click;
            btnRemove.Text = "Remove";
            layout.Controls.Add(btnRemove);

            Load+=new EventHandler(Form1_Load);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            _employees = new BindingList<Employee>();
            for (int i = 0; i < 10; i++)
            {
                _employees.Add(new Employee() { Id = i, Name = "Employee " + i.ToString() }); 
            }

            lstEmployees.DisplayMember = "Name";
            lstEmployees.DataSource = _employees;

            txtId.DataBindings.Add("Text", _employees, "Id");
            txtName.DataBindings.Add("Text", _employees, "Name");
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {
            Employee selectedEmployee = (Employee)lstEmployees.SelectedItem;
            if (selectedEmployee != null)
            {
                _employees.Remove(selectedEmployee);
            }
        }
    }
}
于 2010-01-25T20:09:43.900 に答える
16
typeof(ListBox).InvokeMember("RefreshItems", 
  BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod,
  null, myListBox, new object[] { });
于 2011-01-08T00:02:04.513 に答える
9

リストボックスの datasource と datasource プロパティの間に datasource プロパティと BindingSource オブジェクトを使用します。次に、それをリフレッシュします。

追加された例を更新します。

そのようです:

Public Class Form1

    Private datasource As New List(Of NumberInfo)
    Private bindingSource As New BindingSource

    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
        MyBase.OnLoad(e)

        For i As Integer = 1 To 3
            Dim tempInfo As New NumberInfo()
            tempInfo.Count = i
            tempInfo.Number = i * 100
            datasource.Add(tempInfo)
        Next
        bindingSource.DataSource = datasource
        ListBox1.DataSource = bindingSource
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        For Each objItem As Object In datasource
            Dim info As NumberInfo = DirectCast(objItem, NumberInfo)
            info.Count += 1
        Next
        bindingSource.ResetBindings(False)
    End Sub
End Class

Public Class NumberInfo

    Public Count As Integer
    Public Number As Integer

    Public Overrides Function ToString() As String
        Return String.Format("{0}, {1}", Count, Number)
    End Function
End Class
于 2008-09-14T15:49:27.040 に答える
2

ListBox から派生する場合は、呼び出すことができる RefreshItem 保護メソッドがあります。このメソッドを独自の型で再公開するだけです。

public class ListBox2 : ListBox {
    public void RefreshItem2(int index) {
        RefreshItem(index);
    }
}

次に、デザイナー ファイルを変更して、独自の型 (この場合は ListBox2) を使用します。

于 2008-09-14T23:05:34.153 に答える
0

少し専門的ではありませんが、機能します。アイテムを削除して追加しました(また、アイテムを再度選択しました)。リストは「表示および変更された」プロパティに従ってソートされていたので、やはり私にとっては問題ありませんでした。副作用は、追加のイベント(インデックスが変更された)が発生することです。

if (objLstTypes.SelectedItem != null)
{
 PublisherTypeDescriptor objType = (PublisherTypeDescriptor)objLstTypes.SelectedItem;
 objLstTypes.Items.Remove(objType);
 objLstTypes.Items.Add(objType);
 objLstTypes.SelectedItem = objType;
}
于 2009-05-30T19:03:43.827 に答える
-1

私はvb.netについてあまり知りませんが、C#ではデータソースを使用してから呼び出してバインドする必要がありますlistbox.bind()

于 2008-09-14T17:00:12.393 に答える
-3

objLstTypes が ListBox 名の場合 objLstTypes.Items.Refresh(); を使用します。これがうまくいくことを願っています...

于 2009-06-14T20:06:26.900 に答える