how can i delete items in multiselectlist
My code's working not correctly
for (int i = MyListBox.Items.Count - 1; i >= 0; i--)
//for (int i = -1; i <= MyListBox.Items.Count; i++)
{
if (MyListBox.IsSelectionEnabled == true)
{
MyObservable.RemoveAt(i);
}
}
MyListBox : multiSelectList
MyObservable : ObservableCollection<>
you are unable to remove the items because you are altering the collection while trying to use the collection. You need to gather the items you want to delete, then delete them as such:
ICollection<Item> selectedItems = new List<Item>(MyListBox.SelectedItems.Count);
foreach (var item in MyListBox.SelectedItems)
{
Item myItem = item as Item;
if (myItem == null) continue;
selectedItems.Add(myitem);
}
foreach (var item in selectedItems)
{
MyObservable.Remove(item);
}
MyListBox.IsSelectionEnabled = false;
Related
I have a scroll area with a layout that has 8 of the same custom widgets that have been added to it. This custom widget has a getter function that will return a value. My question is how to get back that original custom widget so I can call the getter function to retrieve the data it stores?
I have added the custom widget to the layout this way:
for (int var = 0; var < 9; ++var) {
calcRow *CalcWidget = new calcRow(this, &js, KeyList, SizeList);
connect(CalcWidget, &calcRow::testSignal, this, &MainWindow::getRowData);
ui->scrollArea_layout->layout()->addWidget(CalcWidget);
}
Where I am stuck:
void MainWindow::getRowData()
{
for (int i = 0;i < ui->scrollArea_layout->layout()->count() ;++i ) {
QWidget *row = ui->scrollArea_layout->layout()->itemAt(i)->widget();
if(row != NULL)
{
std::cout << row->"SOMETHING TO GET CALCROW WIDGET" <<std::endl;
}
}
}
Usually it's not the best structure for your code, any layout change might break your implementation. For example this solution will not work if you will have multiple calcRow widgets.
To make it better, you can pass required parameters which you want use inside getRowData as a parameters of testSignal signal.
Or just simplify it even more with lambda:
for (int var = 0; var < 9; ++var) {
calcRow* CalcWidget = new calcRow(this, &js, KeyList, SizeList);
connect(CalcWidget, &calcRow::testSignal, [CalcWidget]()
{
std::cout << CalcWidget->"SOMETHING TO GET CALCROW WIDGET" << std::endl;
});
ui->scrollArea_layout->layout()->addWidget(CalcWidget);
}
For anyone else that will find this in the future, the comments helped a bunch and I ended up using static_cast. My final code looks like this:
void MainWindow::getRowData()
{
for (int i = 0;i < ui->scrollArea_layout->layout()->count() ;++i ) {
QWidget *row = ui->scrollArea_layout->layout()->itemAt(i)->widget();
calcRow *rowConverted = static_cast<calcRow*>(row);
if(row != NULL)
{
std::cout << rowConverted ->getData() <<std::endl;
}
}
}
I am making a music player program using MFC.
I would like to add a function to select multiple values in the listbox and delete them, but I would like to ask for advice.
The option of the listbox is Extended, and multiple selection using the control keys is fine.
Among the methods of listbox, it seems to be possible to use SetSel, GetCursel, GetSelItems, etc, but I can't solve it.
I would appreciate it if you could give me a simple advice.
Thank you very much.
void CMFC_MP3Dlg::DeleteList(CStatus* head)
{
CFileFind finder;
CString strTemp;
CString strRemoveFile;
POSITION pos;
CStatus* pTemp = new CStatus();
CStatus* pPrev = new CStatus();
//int nSelCount = m_ListBox.GetCurSel();
//m_ListBox.GetText(nSelCount, strTemp);
LPINT lpSelItems = new int[m_nListBoxCount];
m_ListBox.GetSelItems(m_nListBoxCount, lpSelItems);
for (int nCount = 0; nCount <= m_nListBoxCount; nCount ++)
{
if(m_ListBox.SetSel(nCount,1))
{
m_ListBox.GetText(nCount, strTemp);
m_vec.push_back(strTemp);
}
}
std::vector<CString>::iterator iter;
for(iter = m_vec.begin(); iter != m_vec.end();)
{
strRemoveFile.Format(_T("C:\\MFC_MP3\\%s"), *iter);
BOOL bRet = finder.FindFile(strRemoveFile);
if(bRet)
{
if(DeleteFile(strRemoveFile))
{
pPrev = NULL;
pTemp = head;
if(pTemp == NULL)
{
return;
}
while(pTemp->m_strFileName != strTemp)
{
pPrev = pTemp;
pTemp = pTemp->m_right;
}
if(pTemp->m_strFileName == strTemp)
{
pPrev->m_right = pTemp->m_right;
pTemp->m_right->m_left = pPrev;
delete pTemp;
}
MessageBox(_T("삭제 성공!"));
ShowList();
}
else
{
MessageBox(_T("삭제 실패!"));
}
}
else
{
MessageBox(_T("File Not Found!"));
}
iter++;
}
}
Does this help?
void CChristianLifeMinistryPersonalCopiesDlg::BuildSelectedArray()
{
int i, iSize, *pIndex;
CString strText;
m_aryStrPublishers.RemoveAll();
// get selected count
iSize = m_lbPublishers.GetSelCount();
if (iSize > 0)
{
pIndex = new int[iSize];
m_lbPublishers.GetSelItems(iSize, pIndex);
for (i = 0; i < iSize; i++)
{
m_lbPublishers.GetText(pIndex[i], strText);
m_aryStrPublishers.Add(strText);
}
delete[] pIndex;
}
}
This works fine for me.
Note that your code is incomplete though. We don't see you specify what the count is of the selected items. And we don't see you reset your vector array before you begin.
Have you actually debugged your code to see where it fails?
i have the following list with duplicate values and i need to check if the values is duplicated print it else skip it
List lst = ["AA","BB","BBB","AA"];
what should printed is :
AA
Thanks ;
Would this work for you?
List list = ["AA", "BB", "BBB", "AA"];
List distinctList = list.toSet().toList();
void main() {
for (int i = 0; i < distinctList.length; i++) {
list.remove(distinctList[i]);
}
//// or you could use a "for in" like this:
// for (var item in distinctList) {
// list.remove(item);
// }
print(list.toSet().toList());
}
Or using forEach() on the Set
List list = ['AA', 'BB', 'BBB', 'AA'];
void main() {
list.toSet().forEach((item) => {list.remove(item)});
print(list.toSet().toList());
}
List lst = ["AA","BB","BBB","AA"];
int duplicateDetectedCount = -1;
String duplicateItem = "";
for(String item in lst){
for(String innerItem in lst){
if(item == innerItem){
duplicateDetectedCount++;
if(duplicateDetectedCount == 1){
duplicateItem = innerItem;
}
}
}
}
print(duplicateItem); // prints AA
lst.where((e) => lst.where((element) => element == e).length > 1).toSet().toList();
One Liner
I have a text file called highscore.txt and I know the format of the data going into the file which works in the following way:
Username:score
I then need to search through the whole file to see where the new score needs to be added such that the file is in order of score from largest to smallest
List<string> tempoaryList = new List<string>();
List<int> valueList = new List<int>();
string lineValues = "";
using (StreamReader sr = new StreamReader(finalPath))
{
while (sr.EndOfStream == false)
{
lineValues = sr.ReadLine();
tempoaryList.Add(lineValues);
int data = Convert.ToInt32(lineValues.Substring(lineValues.LastIndexOf(':') + 1));
valueList.Add(data);
}
}
valueList.Sort();
for(int i =0; i > valueList.Count; i++)
{
if(valueList[i] <= playerScore)
{
tempoaryList.Insert(i - 1, playerScore.ToString());
}
}
using (StreamWriter sw = new StreamWriter(finalPath, false))
{
for (int i = 0; i < tempoaryList.Count; i++)
{
sw.WriteLine(tempoaryList[i]);
Debug.Log(tempoaryList[i]);
}
}
The above just simply doesn't change the text file and leaves it as it was found, any ideas of what I am doing wrong?
You should change your code to this:
ScoreList.cs
using UnityEngine;
using System;
using System.IO;
using System.Collections.Generic;
public class ScoreList : MonoBehaviour {
private void Start() {
GameOver.GameOverEvent += UpdateScoreBoardFile;
}
private void UpdateScoreBoardFile(string playerName, int playerScore) {
string lineValues;
string finalPath = "[ScoreBoard File Location]";
List<string> tempoaryList = new List<string>();
List<int> valueList = new List<int>();
bool isScoreLowest = true;
using (StreamReader sr = new StreamReader(finalPath)) {
while (sr.EndOfStream == false) {
lineValues = sr.ReadLine();
tempoaryList.Add(lineValues);
int data = Convert.ToInt32(lineValues.Substring(lineValues.LastIndexOf(':') + 1));
valueList.Add(data);
}
}
if (tempoaryList != null) {
for (int i = 0; i < valueList.Count; i++) {
if (valueList[i] <= playerScore) {
tempoaryList.Insert(i, playerName + ":" + playerScore.ToString());
isScoreLowest = false;
break;
}
}
}
if (isScoreLowest) {
tempoaryList.Add(playerName + ":" + playerScore.ToString());
}
using (StreamWriter sw = new StreamWriter(finalPath, false)) {
for (int i = 0; i < tempoaryList.Count; i++) {
sw.WriteLine(tempoaryList[i]);
Debug.Log(tempoaryList[i]);
}
}
}
}
GameOver.cs (or wherever you manage the game over condition):
using UnityEngine;
using System;
public class GameOver : MonoBehaviour {
public static event Action<string, int> GameOverEvent;
string playerName;
int finalScore;
private void GameOver() {
//Do other stuff when the game is over
GameOverEvent(playerName, finalScore);
}
}
Explanation of the changes:
isScoreLowest is needed to Add the new lowest score at the end of the list, since the for loop won't add it by itself.
The if (tempoaryList != null) check is done to skip the for loop when the scoreboard is empty.
And you saved yourself from doing a Sort, which is always a good thing. :)
I am trying to add two items into my QListWidget dynamically. However, the following codes only allow me to add only the last item into the list. strList.size() contains 4 items. Assuming name contains "ABC 1" and "ABC 2".
Is my loop incorrect? Or is my method of adding items into the listWidget wrong?
.h:
public:
QListWidgetItem *item[2];
.cpp:
...
while(!xml.atEnd())
{
xml.readNextStartElement();
if(xml.isStartElement())
{
if(xml.name() == "OS")
{
strList << xml.readElementText();
}
}
}
int num = 0;
for(int i = 0; i < strList.size(); i++)
{
if(strList[i] == "ABC")
{
QString name = strList[i] + strList[i+1];
item[num] = new QListWidgetItem();
item[num]->setText(name);
ui.listWidget->insertItem(num, item[num]);
num += 1;
}
}
Output (listWidget):
ABC02
Expected output (listWidget):
ABC01 ABC02