I am updating older code but part of it must stay the same. I have now picker that needs to be filled with list.
My list
public List<TimeoutBetweenSentences> FillTimoutOptions()
{
var newListTimeoutBetweenSentenceses = new List<TimeoutBetweenSentences>()
{
new TimeoutBetweenSentences()
{
Position = 0,
Text = "+ 0 sekund",
Value = 0
},
new TimeoutBetweenSentences()
{
Position = 1,
Text = "+ 1 sekunda",
Value = 1
},
new TimeoutBetweenSentences()
{
Position = 2,
Text = "+ 2 sekundy",
Value = 2
},
new TimeoutBetweenSentences()
{
Position = 3,
Text = "+ 3 sekundy",
Value = 3
},
new TimeoutBetweenSentences()
{
Position = 4,
Text = "+ 4 sekundy",
Value = 4
},
new TimeoutBetweenSentences()
{
Position = 5,
Text = "+ 5 sekund",
Value = 5
},
};
return newListTimeoutBetweenSentenceses;
}
List<TimeoutBetweenSentences> allOptions = FillTimoutOptions();
sentencePausesStepper.Items.Add(allOptions.Select(m => m.Text).ToList().ToString());
however this displays just as "System collections" DO zou have any idea?
this is adding an entire list as ONE element
sentencePausesStepper.Items.Add(allOptions.Select(m => m.Text).ToList().ToString());
to add elements of one list to another, use AddRange instead
sentencePausesStepper.Items.AddRange(allOptions.Select(m => m.Text).ToList().ToString());
or better, do this
sentencePausesStepper.ItemsSource = allOptions;
sentencePausesStepper.ItemDisplayBinding = new Binding("Text");
Related
I am trying to get into more complex Linq queries and right away catch a point I am feeling stuck. I have a following list in DB:
ID ELAPSED TIME APPISRUNNING
1 12 TRUE
2 54 TRUE
3 32 FALSE
Where ELAPSED TIME is TimeSpan and APPISRUNNING is a bool.
I would like to build a chart based on these values (https://github.com/beto-rodriguez/LiveCharts2). Chart build fine with this:
Title = "Analytics";
this.ActivityChartSeries = new ISeries[]
{
new PieSeries<double> { Values = new double[] { 2 }},
new PieSeries<double> { Values = new double[] { 2 }},
new PieSeries<double> { Values = new double[] { 2 }},
new PieSeries<double> { Values = new double[] { 2 }},
new PieSeries<double> { Values = new double[] { 2 }},
};
Now I somehow need to first GroupBy bool and then select a new List? I have tried following:
IEnumerable<DataRecord> dataRecords = await this.DataStore.GetItemsAsync();
this.ActivityChartSeries = dataRecords
.GroupBy(g => g.AppIsRunning)
.Select(m => new
{ // BELOW IS TOTALLY UNCLEAR FOR ME
Values = m.Select(r => r.EngineElapsed.Ticks),
Name = m.Select(r => r.Name),
})
.Select(x =>
new PieSeries<double>
{
Values = new List<double> { x.Values.FirstOrDefault() },
Name = x.Name.FirstOrDefault(),
});
Type of assigned variable:
public IEnumerable<ISeries> ActivityChartSeries
This part is totally unclear for me:
Values = m.Select(r => r.EngineElapsed.Ticks),
Name = m.Select(r => r.Name),
How after GroupBy I can create two types of data? Basically I need
"Application Running" and "Values"
"Application is not Running" and "Values"
EDIT:
Code provided by Somar Zein compiles fine:
var results = activityChartSeries
.GroupBy(a=> a.AppIsRunning)
.Select(item=> new PieSeries<double>{
Name = item.Key ? "Application is Running" : "Application is not Running",
Values = item.Select(x=> Convert.ToDouble(x.ElapsedTime.Ticks)).ToList()
});
However as a result I am getting something like this, why it is reloading in a loop?
Here is result:
enter image description here
EDIT2:
So I have created an example for testing purposes:
Class:
public class DataModel
{
public int Id { get; set; }
public TimeSpan ElapsedTime { get; set; }
public bool AppIsRunning { get; set; }
}
Code:
List<DataModel> records = new List<DataModel>();
records.Add(new DataModel { Id = 1, ElapsedTime = new TimeSpan(1, 20, 30), AppIsRunning = true });
records.Add(new DataModel { Id = 2, ElapsedTime = new TimeSpan(1, 20, 30), AppIsRunning = true });
records.Add(new DataModel { Id = 3, ElapsedTime = new TimeSpan(1, 20, 30), AppIsRunning = true });
records.Add(new DataModel { Id = 4, ElapsedTime = new TimeSpan(1, 20, 30), AppIsRunning = true });
records.Add(new DataModel { Id = 5, ElapsedTime = new TimeSpan(1, 20, 30), AppIsRunning = true });
this.ActivityChartSeries = records
.GroupBy(g => g.AppIsRunning)
.Select(item => new PieSeries<double>
{
Name = item.Key ? "Running" : "Not Running",
Values = new double[] { 2, 4 },
});
I get the same reloading effect, even thou originally provided Example from LiveCharts work fine.
you could try doing something like following:
var results = activityChartSeries
.GroupBy(a=> a.AppIsRunning)
.Select(item=> new PieSeries<double>{
Name = item.Key ? "Application is Running" : "Application is not Running",
Values = item.Select(x=> Convert.ToDouble(x.ElapsedTime.Ticks)).ToList()
});
hope that could be helpful!
I have created a grid in my Xamarin application which has 4 rows and 24 columns.
I have 12 buttons that use the same properties, so to save myself creating all 12 separately, I have done it like this
var functionButton = new Style(typeof(Button))
{
Setters = {
new Setter { Property = BackgroundColorProperty, Value = Color.FromHex ("#F0E68C") },
new Setter { Property = Button.TextColorProperty, Value = Color.Black },
new Setter { Property = Button.CornerRadiusProperty, Value = 0 },
new Setter { Property = Button.FontSizeProperty, Value = 10 }
}
};
then add them to the grid as below
controlGrid.Children.Add(new Button { Text = "End" + Environment.NewLine + "Sale", Style = functionButton }, 0, 0);
controlGrid.Children.Add(new Button { Text = "Repeat" + Environment.NewLine + " Last", Style = functionButton }, 1, 0);
controlGrid.Children.Add(new Button { Text = "Void" + Environment.NewLine + "Line", Style = functionButton }, 2, 0);
and so on, until all 12 have been added.
However, I want each button to take up 2 columns.
Usually, if I'd created the buttons separately I could use Grid.SetColumnSpan(Button1, 2);
But that doesn't seem very efficient, as I'd need to create all 12 buttons separately. Is there another way that I can set the column span using this method of creating the buttons that I've currently got?
You can use a for loop.
var btnLabels = new[] {
"End" + Environment.NewLine + "Sale",
"Repeat" + Environment.NewLine + " Last",
"Void" + Environment.NewLine + "Line"
};
Button buttonCtrl;
for (int row= 0; row < btnLabels.Length; row++)
{
buttonCtrl = new Button { Text = btnLabels[row], Style = functionButton };
Grid.SetColumnSpan(btn, 2);
controlGrid.Children.Add(btn, row, 0);
}
I have this list of Debit object
List<Debit> debits = new List<Debit>()
{
new Debit { Code = "A001", Length = 100, Qte = 3, Position = "MCD" },
new Debit { Code = "A001", Length = 100, Qte = 2, Position = "MED" },
new Debit { Code = "A001", Length = 200, Qte = 1, Position = "MCG" },
new Debit { Code = "A002", Length = 200, Qte = 1, Position = "MCD" },
new Debit { Code = "A003", Length = 200, Qte = 1, Position = "TBD" }
};
and I try to group Debit by Code and Length, sum the Qte property of grouped lines and join the Position string separated by a comma ", " in a new list of Debit named sortedDebit.
sortedDebit :
Code = "A001", Length = 100, Qte = 5, Position = "MCD, MED"
Code = "A001", Length = 200, Qte = 1, Position = "MCG"
Code = "A002", Length = 200, Qte = 1, Position = "MCD"
Code = "A003", Length = 200, Qte = 1, Position = "TBD"
Is there a way using linq to do that?
Sure there is. You can group by the combination of the two fields into a new composite key, which is a simple anonymous object. This requires that each of the fields making up the new composite key is equatable either by object reference or because it has a valid GetHashCode and Equals implementation.
var grouped = debits
.GroupBy(d => new { Code = d.Code, Length = d.Length })
.Select(g => new Debit() {
Code = g.Key.Code,
Length = g.Key.Length,
Qte = g.Sum(x => x.Qte),
Position = string.Join(", ", g.Select(x => x.Position).Distinct())
});
I am having a real problem iterating a list<list<object>> and would like to ask anybody for their insight.
as you can see I have a list<list<object>> posCheckOptions which contains 32 lists and each list contains x amount of objects, i.e 348 for 0, 325 for 1 etc.
for example, in this list of 348 there are duplicate elements which I would like to remove. in duplicate I mean, the name of the stock could be the same so, if I have say, VODAFONE 4 times, I would like to add the qty of shares from each one to the first time Vodafone is spotted and delete the duplicates.
for(int k = 0; k<posCheckOptions.Count; k++)
{
int l = 0;
int m = 1;
while (l != m)
{
foreach(var x in posCheckOptions[k][l].name)
{
if(posCheckOptions[k][l].date != posCheckOptions[k][m].date
&& posCheckOptions[k][l].strike != posCheckOptions[k][m].strike
&& posCheckOptions[k][l].callPut != posCheckOptions[k][m].callPut)
{
m++;
}
else
{
posCheckOptions[k][l].size = posCheckOptions[k][l].size + posheckOptions[k][m].size;
posCheckOptions[k].RemoveAt(m);
m--;
}
}
l++; m = l;
}
}
What I am trying to code, well at least the idea is, I start from posCheckOptions[0][0] and compare elements posCheckOptions[0][0].date to posCheckOptions[0][1].date (i compare 4 fields) (poscheckOptions is a list whos type T is a class with 76 varaibles). If what I compare is not equal (i.e. not duplicate I move the index up level and continue to the next, so on. On my travels if I find a duplicate element, i do the addition and remove, move the index back one and start until I reach the end.
im getting confused with the fact, im not sure if i need 2 index running in j posCheckOptions[0][j] because j only goes to j+1 once say index m has looped all 348 elements. This may not be 348 if i delete 2....
any advice is really welcome :-)
Looks like your problem can be easily solved using LINQ. I'm gonna show it on simplified example, so you'll have to adjust it you your real one.
Assume we have a class names Item as following:
public class Item
{
public int Key { get; set; }
public int SubKey { get; set; }
public int Quantity { get; set; }
}
And a list (List<Item>):
var items = new List<Item>() {
new Item { Key = 1, SubKey = 1, Quantity = 100 },
new Item { Key = 1, SubKey = 2, Quantity = 400 },
new Item { Key = 2, SubKey = 1, Quantity = 60 },
new Item { Key = 1, SubKey = 1, Quantity = 10 },
new Item { Key = 2, SubKey = 1, Quantity = 30 },
new Item { Key = 1, SubKey = 1, Quantity = 70 }
};
Now, we'd like to sum Quantity for elements with the same pair of Key and SubKey (what will also remove duplicates). There is GroupBy method within LINQ, so let's use it:
var groupedItems = items.GroupBy(x => new { x.Key, x.SubKey })
.Select(g => new Item {
Key = g.Key.Key,
SubKey = g.Key.SubKey,
Quantity = g.Sum(x => x.Quantity)
}).ToList();
As a result, we have a new List<Item> with only one element for every Key/SubKey pair and Quantity which is a sum of Quantities for items with that key pair.
Can it be expanded for <List<List<Item>> as an input and output? Sure it can.
Source nested Items collection:
var nestedItems = new List<List<Item>>() {
new List<Item>() {
new Item { Key = 1, SubKey = 1, Quantity = 100 },
new Item { Key = 1, SubKey = 2, Quantity = 400 },
new Item { Key = 2, SubKey = 1, Quantity = 60 },
new Item { Key = 1, SubKey = 1, Quantity = 10 },
new Item { Key = 2, SubKey = 1, Quantity = 30 },
new Item { Key = 1, SubKey = 1, Quantity = 70 }
},
new List<Item>() {
new Item { Key = 1, SubKey = 1, Quantity = 100 },
new Item { Key = 1, SubKey = 2, Quantity = 400 },
new Item { Key = 2, SubKey = 1, Quantity = 60 },
new Item { Key = 1, SubKey = 1, Quantity = 10 },
new Item { Key = 2, SubKey = 1, Quantity = 30 },
new Item { Key = 1, SubKey = 1, Quantity = 70 }
},
new List<Item>() {
new Item { Key = 1, SubKey = 1, Quantity = 100 },
new Item { Key = 1, SubKey = 2, Quantity = 400 },
new Item { Key = 2, SubKey = 1, Quantity = 60 },
new Item { Key = 1, SubKey = 1, Quantity = 10 },
new Item { Key = 2, SubKey = 1, Quantity = 30 },
new Item { Key = 1, SubKey = 1, Quantity = 70 }
}
};
And the query:
var nestedGroupedItems = nestedItems.Select(x => x.GroupBy(y => new {y.Key, y.SubKey })
.Select(g => new Item {
Key = g.Key.Key,
SubKey = g.Key.SubKey,
Quantity = g.Sum(y => y.Quantity)
}).ToList()).ToList();
I would suggest to do the following:
Implement the IComparable interface to the type of which the objects in the lists are. This way you can store the comparison logic inside the type itself.
Create a list of this type (just like the lists in posCheckOptions). Lets call it bigList
iterarte over all lists in posCheckOptions
iterate over each item in the contained list and check if the item is contained in bigList. If it is, delete it from the current inner list. If not add it to bigList
I'm making some assumptions about the Type that contains your stock information, feel free to adjust as necessary. What you can do is create a dictionary mapping stock names to the stock objects. Update the object in the dictionary if it exists, or add it to the dictionary.
var allStock = mylist.SelectMany(l => l.Select(inner => inner));
var lookup = new Dictionary<string, Stock>();
foreach (var stock in allStock)
{
if (!lookup.ContainsKey(stock.Name)) {
lookup.Add(stock.Name, stock);
continue;
}
lookup[stock.Name].Quantity += stock.Quantity;
}
Now you have a dictionary mapping the names of stock to the actual stock. Just iterate over the values to get a list back out if that's what you need.
I am using a ListBox and the data is a class:
private class Duration
{
public int Value { get; set; }
public string Label { get; set; }
}
I bind the class in this way:
var durations = new List<Duration>()
{
new Duration() { Value = 5, Label = "5 minutes" },
new Duration() { Value = 10, Label = "10 minutes" },
new Duration() { Value = 15, Label = "15 minutes" },
new Duration() { Value = 30, Label = "30 minutes" },
new Duration() { Value = 45, Label = "45 minutes" },
new Duration() { Value = 60, Label = "1 hour" },
new Duration() { Value = 90, Label = "1 hour and half" }
};
this.listTime.DataSource = durations;
this.listTime.DisplayMember = "Label";
this.listTime.ValueMember = "Value";
Everything works fine and the labels are show.
When i go to read the selected value, I am not able to recover the value of the selected item.
I was expecting to be able to do this:
int value = listTime.SelectedItems[0].Value;
or at least this:
Duration value = listTime.SelectedItems[0];
but this gives me error, what I am doing wrong? How is the right way to get the value of the selected item on the ListBox?
if (listTime.SelectedIndex != -1)
{
var item = listTime.SelectedItem as Duration;
//or as suggested by 'Stu'
var item = (Duration)listTime.SelectedItem;
MessageBox.Show(item.Value.ToString());
}
If you use Listbox this code is Ok:
listTime.Items[0].Value