簡體   English   中英

將 object 變量作為字符串傳遞給 WPF/C# 中的文本框

[英]Pass an object Variable as a String to a Textbox in WPF/C#

我正在創建一個練習應用程序來練習使用文本文件作為數據庫。

  1. 拿一個帶有 14 個人數據條目的 pipe 划定文本文件
  2. 拆分管道上的文本文件並將每個條目添加到將每個條目(大約 150 個)添加到對象列表中。
  3. 我已將對象列表轉換為字符串。

現在我想要單擊按鈕以在文本框中顯示該列表。

這是代碼。

namespace StaffRosterLewis.ViewModel
{
    class LoadData
    {
        public static void LoadRosterData()
        {

            
            string mypath = @"J:\zUtilities - Program Files\";
            mypath += "StaffRoster - RosterOld.txt";
            List<Model.Person> people = new List<Model.Person>();
            List<string> lines = File.ReadAllLines(mypath, Encoding.ASCII).ToList();

            foreach (var line in lines)
            {
                string[] entries = line.Split('|');

                Model.Person newPerson = new Model.Person
                {
                    LastName = entries[1],
                    FirstName = entries[2],
                    Extension = entries[3],
                    Department = entries[4],
                    Team = entries[5],
                    Group = entries[6],
                    Title = entries[7],
                    Shift = entries[8],
                    EmergencyResponder = entries[9],
                    AEDCPRCert = entries[10],
                    Languages = entries[11],
                    Notary = entries[12],
                    Note = entries[13],
                    DutyLocation = entries[14]
                };
                //newPerson.Unknown15 = entries[15];

                people.Add(newPerson);


            }
            people.ToString();
            
        }
    }
}

我認為問題出在按鈕點擊發生的地方。 我只是想顯示上面的人的內容,但無論我如何嘗試引用它,我都會丟失變量“人”。 上面的代碼是公開的,我把它寫成 static,所以 people 變量應該可以在項目中的任何地方訪問。 (我想)

 private void Button_Show_Click(object sender, RoutedEventArgs e)
        {
            Button_Show.Content = $"{LoadData.LoadRosterData.people.ToString()}";
        }

你的代碼有很多問題。

您正在嘗試在此處訪問類似 static 屬性的方法。

其次,你有返回類型 void,它應該是字符串類型。

第三,您應該覆蓋 ToString 方法以將列表項作為字符串以所需格式返回。

您應該使用Path.Combine來獲取路徑。

如果您打算將people設置為 static 變量,那么您必須接受它不是線程安全的,並確保在必要時重置它,否則您可能會在列表中遇到意想不到的項目。

如果少於 15 | ,您的代碼將拋出異常。 在一條線上

您不需要制作LoadRosterData static 但是,正如其他評論者所提到的,該方法必須返回一個結果(在您當前使用的上下文中)。

  • 因為從文件中讀取可能會消耗資源,所以將結果存儲在公共屬性Peoples中時可以提高性能。
    這允許訪問集合而無需強制讀取可能未更改的文件。 由於這意味着引入實例變量,因此建議也將LoadRosterData實例成員。

  • 要從集合中創建字符串,您可以使用StringBuilder 下面的示例使用StringWriter ,它允許異步創建字符串。 StringWriter還在內部使用StringBuilder

  • 您可以通過覆蓋 Person 類型的ToString來進一步改進代碼。

  • 要提高文件讀取性能,您應該使用StreamReader的異步 API 而不是同步File class。使用StreamReader.ReadLineAsync還將為您節省一個額外的循環。

  • 為了使文件處理和數據 model 的創建更加方便,您應該考慮使用序列化。
    推薦的文本格式為 JSON。請參閱Microsoft 文檔:如何序列化和反序列化(編組和反編組).NET 中的 JSON了解如何操作。 反序列化 JSON 文件(最好是異步的)將自動生成一個Person項目的集合,沒有任何麻煩(這將消除丑陋和脆弱的基於索引的訪問(初始化實例屬性)以及使任何分隔符像你的 pipe '|' 多余) .

  • 您正在訪問從索引“1”開始的數組。 但在計算機科學中,索引總是從“0”開始。 不確定您是否故意從索引“1”開始。

以下代碼修復了一些問題並實現了一些性能改進。 它還展示了如何將集合轉換為string ,其中每個Person項目都顯示在它自己的行中:

PersonDataReader.cs

class PersonDataReader
{
  // Consider to use an ImmutableList to prevent modification.
  // In the current context, this property could (and probably should) defined private.
  public List<Person> Persons { get; }

  // If Person is private, 'HasData' has to be defined private too
  public bool HasData => this.Persons.Any();

  // Constructor
  public PersonDataReader() => this.Persons = new List<Person>();

  public async Task<string> CreateRosterSummaryAsync()
  {
    // Use StringWriter to enable asynchronous string creation.
    // StringWriter also uses a StringBuilder internally to improve performance.
    using (var textWriter = new StringWriter())
    {
      if (!this.HasData)
      {
        await LoadRosterDataAsync();
      }

      // Alternatively use LINQ, 
      // for example Enuemrable.Select together with Enumerable.Aggregate
      // to concatenate the Person.ToString values
      foreach (Person person in this.Persons)
      {
        string personString = person.ToString();

        // Write a Person per line
        await textWriter.WriteLineAsync(personString);
      }

      return textWriter.ToString();
    }
  }

  private async Task LoadRosterDataAsync()
  {
    this.Persons.Clear();

    // Use Path.Combine to ensure a valid formatted path (improve robustness)
    string sourcePath = Path.Combine(@"J:\zUtilities - Program Files", "StaffRoster - RosterOld.txt");

    // Test if the file actually exists to avoid the expensive exception.
    // If the file not found exception is desired, remove the File.Exists condition.
    if (File.Exists(sourcePath))
    {
      return;
    }

    using (var fileReader = new StreamReaeder(sourcePath, Encoding.ASCII))
    {
      while (!fileReader.EndOfFile)
      {
        var line = await reader.ReadLineAsync();
        string[] personValues = line.Split('|', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);

        // If you would use serialization, constructing the type explicitly
        // can be avoided. A recommended text format to allow easy de-/serialization is the JSON format.
        var newPerson = new Model.Person 
        {
          // Check if starting from index '1' is really correct
          LastName = personValues[1],
          FirstName = personValues[2],
          Extension = personValues[3],
          Department = personValues[4],
          Team = personValues[5],
          Group = personValues[6],
          Title = personValues[7],
          Shift = personValues[8],
          EmergencyResponder = personValues[9],
          AEDCPRCert = personValues[10],
          Languages = personValues[11],
          Notary = personValues[12],
          Note = personValues[13],
          DutyLocation = personValues[14]
        };

        this.Persons.Add(newPerson);
      }
    }       
  }
}

人物.cs

class Person
{
  /* Properties of Person */

  // Example text representation of a 'People' object
  // using string interpolation
  public override string ToString()
    => $"Lastname: {this.LastName}; Firstname: {this.FirstName}; Duty location: {this.DutyLocation}"; 
}

MainWindow.xaml.cs

partial class MainWindow : Window
{
  private PersonDataReader PersonDataReader { get; }

  public MainWindow()
  {
    InitializeComponent();

    this.PersonDataReader = new PersonDataReader();
  }

  private async void Button_Show_Click(object sender, RoutedEventArgs e)
  {    
    string personPerLineText = await this.PersonDataReader.CreateRosterSummaryAsync();

    // Why did you chose a Button here? It should be
    // this.DisplayTextBox.Text = personPerLineText;
    this.Button_Show.Content = personPerLineText;

    // Consider to display the complete List<Person> in a ListBox.
  }
}

評論

ListBox可能是顯示Person列表的更好選擇。 實現起來更直觀,並且無需擔心字符串表示和創建。

您的方法LoadRosterData有一個返回值void ,沒有任何意義。 如果你想返回一個字符串值並使用它,你可以這樣做:

//returns a string
public static string MyStringMethod()
{
     string str = "My string";
     //Specify the return value with the return keyword
     return str;
}

或者如果你想返回一個列表:

public static List<string> MyListMethod()
{
     List<string> list = new List<string>();
     list.Add("one");
     list.Add("two");
     list.Add("three");
     return list;
}

你不能用列表做ToString() ,但你可以引用一個人的索引。 和用法:

button.Content = $"{MyStringMethod()}"

或者如果你想通過名字獲取人,你可以使用IndexOf()方法:

List<string> list = new List<string>();
list.Add("one");
list.Add("two");
list.Add("three");

string number = "one";

button.Content = $"list[list.IndexOf(number)]";

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM