Get number of items in repeater during OnItemDataBound - c#

I'm trying to get the number of items in a repeater whilst handling the OnItemDataBound event. What I'm trying to achieve it quite simple; I'm trying to hide a certain label on the last item within a repeater. Currently I'm hooking into the ItemIndex and Items.Count, however as it's during the OnItemDataBound, the index and count are incrementing together.
Here's what I've got so far:
Label myLabel = e.Item.FindControl<Label>("MyLabel");
if (myLabel != null)
{
// as the item index is zero, I'll need to check against the collection minus 1?
bool isLastItem = e.item.ItemIndex < (((Repeater)sender).Items.Count - 1);
myLabel.Visible = !isLastItem;
}
I know that I could cast the DataSource to the collection of data items that were bound, however the OnItemDataBound event handler is being used across multiple repeater, so I'll need something slightly more generic.

Could you do something along the lines of, having set Visible to false by default:
if (e.Item.ItemIndex > 0)
{
var previousItem = ((Repeater)sender).Items[e.Item.ItemIndex - 1];
var previousLabel = previousItem.FindControl<Label>("MyLabel");
if (previousLabel != null)
{
previousLabel.Visible = true;
}
}
I'm not sure if this will work - I didn't know you could access repeater.Items until I saw your code - but it seems plausible.

Related

I'm having trouble adding items from a list to a listBox in Windows Forms

I have a list box in the design and have a list that I'm attempting to load into a ListBox so that I can then select Items from that ListBox. I used the the code from the .Docs page on ListBox class and that doesn't seem to work. As I keep getting a CS1656 error on ltbxCurrentRaceOrder.Items.Add
int count = 0;
ltbxCurrentRaceOrder.BeginUpdate();
while (count != GlobalClass.allNames.Count)
{
ltbxCurrentRaceOrder.Items.Add = GlobalClass.allNames[count];
count = count + 1;
}
ltbxCurrentRaceOrder.EndUpdate();
ltbxCurrentRaceOrder.Items.Add is a function, yet you're using it as a property. Use it like this instead:
ltbxCurrentRaceOrder.Items.Add(GlobalClass.allNames[count]);

Is there a function to save the number of checked checkboxes in a variable?

I have a wpf app with 20 Checkboxes.
Is there a function to Safe the number of the checkboxes which are checked in a variable.
If there is an other possibility to use the number without saving it in a variable first, that would help me too.
Thanks!
There's nothing built-in, but a loop or Linq query shouldn't be too hard. If you want all checkboxes on the form, you could just do
int count = 0;
for (var control in parent.Children)
{
if (control is CheckBox && ((CheckBox)control).IsChecked)
{
count++;
}
}
or
int count = parent.Children.OfType<CheckBox>()
.Where(cb => cb.IsChecked)
.Count();
If you have move specific conditions (e.f. checkboxes that have a specific name pattern), then just add that to the if or Where clause.

How do you add EmptySpaceItems and LayoutControlItems with equal widths to a LayoutControlGroup with DevExpress?

NOTE: All controls described in this question are DEVEXPRESS controls.
I am attempting to programatically add both LayoutControlItems and EmptySpaceItems to a LayoutControlGroup on a DevExpress LayoutControl.
The requirements for my project require that I have a LayoutControlGroup panel that is dependent on a set of filter items chosen from another control on the layout control. If there are no filters chosen, than none of the `LayoutControlItems are shown. If one or more of the filters are chosen that I add one or more of the controls to the group based on the selection.
The way that I attempt to do this is the following:
1) in the designer for the LayoutControl I have already created the LayoutControlGroup with the LayoutControlItems. There are 6 total, and each LayoutControlItem contains a PanelControl that contains a ListBoxControl
2) When the form is initalized I hide each of the LayoutControlItems from the LayoutControlGroup using the LayoutControlItem.HideFromCustomization() method.
3) After the user selects a filter or set of filters I run the following code attempting to restore the control items to the group from left to right.
this.layoutGroupScenarioPortfolios.BeginUpdate();
LayoutControlItem layoutControlToAdd;
LayoutControlItem lastLayoutControlItem = null;
for (int loop = 0; loop < selectedFilters.Length; loop++)
{
layoutControlToAdd = LayoutControlItemFactoryUtil(selectedFilters[loop]);
if (layoutControlToAdd == null)
{
continue;
}
if (loop < 1)
{
layoutControlToAdd.RestoreFromCustomization(this.layoutControlGroupSelectedFilters);
}
else
{
layoutControlToAdd.RestoreFromCustomization(lastLayoutControlItem, DevExpress.XtraLayout.Utils.InsertType.Right);
}
lastLayoutControlItem = layoutControlToAdd;
}
for (int loop = 0; loop < numOfEmptySpaceItemsNeeded; loop++)
{
layoutControlToAdd = new EmptySpaceItem(this.layoutControlGroupSelectedFilters)
{
Owner = this.layoutControlGroupSelectedFilters.Owner
};
layoutControlToAdd.RestoreFromCustomization(lastLayoutControlItem, DevExpress.XtraLayout.Utils.InsertType.Right);
lastLayoutControlItem = layoutControlToAdd;
}
this.layoutControlGroupSelectedFilters.TextVisible = true;
this.layoutGroupScenarioPortfolios.EndUpdate();
As you can see from the code one loop adds the appropriate ListControlBox to the group. The second loop tries to add empty space items to make sure that the list box control does not take up the entire group. By the end of this code there should be 6 items spanning the group control, each with the same width in the control.
The problem is that the first control added takes up half of the group box's space while the other 5 items are equally fitted into the remaining half of the group box.
In the first loop, is the RestoreFromCustomization() method with one parameter the correct method to use?
I would suggest to place the controls at runtime. LayoutControl will manage the LayoutControlGroups and EmptySpaceItems.
Here is the code I had written to place user controls into the LayoutControl at runtime:
LayoutControlItem lastItem = null;
int RowWidth = 0;
public void AddMyControl()
{
MyControl myControl = new MyControl("");
myControl.Name = Guid.NewGuid().ToString();
LayoutControlItem item = new LayoutControlItem();
item.Name = Guid.NewGuid().ToString();
item.Text = "";
MyLayoutControl.BeginUpdate();
//We need to determine where to insert the new item. Right or Below. If there is
//space on the right we insert at Right else we just add the item.
if(lastItem == null || lastItem != null && (MyLayoutControl.Width - UserControlWidth) < RowWidth)
{
MyLayoutControl.AddItem(item);
RowWidth = item.MinSize.Width;
}
else
{
MyLayoutControl.AddItem(item, lastItem, DevExpress.XtraLayout.Utils.InsertType.Right);
}
item.Control = myControl;
RowWidth += item.MinSize.Width;
lastItem = item;
item.Name = " ";
MyLayoutControl.BestFit();
MyLayoutControl.EndUpdate();
}
If you just need left to right controls, flowlayoutpanel will suit better. Sometimes LayoutControl is tough to work with. I had eventually go with flowlayoutpanel as it is much simpler to work with.

C# - Displaying server control based on how many items are in a datalist

What I am trying to do is on page load display either of two controls based on how many items are in a datalist.
For instance, if the datalist only contains 1 item I want it to display
Literal1.Visible = true;
If there is more than 1 item in the datalist, then show
LiteralMulti.Visible = true;
Anyone know how to do this?
Use can simple do that in Page_Load method :
if(DataListName.Items.Count > 1)
{
Literalmulti.Visible = true;
}
else
{
Literalsingle.Visible = true;
}
Check the Count of the Items property.
Literal1.Visible = myDataList.Items.Count == 1;
LiteralMulti.Visible = myDataList.Items.Count > 1;

How do I get the start index and number of visible items in a ListView?

I have a listview working in virtual mode, in the LargeIcons view. Retrieves are expensive, so I want to ask for the data for all the visible items. How do I get the start index and total number of the visible items?
Update: I am aware of the CacheVirtualItems event. The third-party database we're using takes ~3s to retrieve a single record, but ~4s to retrieve a thousand records, so I have to do them in large blocks. I need to make sure the visible records are among those we retrieve, so I need to know the start index and total number of the visible items. If that's not feasible, I'll have to find a workaround (which will probably involve using a DataGridView with a load of image cells to imitate the LargeIcons view) but I would like to do this properly if possible.
THE REAL Answer is :
* get the ScrollViewer of the ListView.
* ScrollViewer.VerticalOffset is the index of first shown item.
* ScrollViewer.ViewportHeight is the number of items shown.
To get the ScrollViewer, you will need a function,
FindDescendant(FrameworkElement, Type) that will search
within the childs of the
ListView. Call it after Window was loaded.
Code in VB.Net and in C# :
Public Function FindDescendant(ByVal MyElementToSeek As FrameworkElement, _
ByVal TypeToFind As Type) As FrameworkElement
If MyElementToSeek Is Nothing Then Return Nothing
If MyElementToSeek.GetType() = TypeToFind Then Return MyElementToSeek
For i = 0 To VisualTreeHelper.GetChildrenCount(MyElementToSeek) - 1
Dim OneChild = TryCast(VisualTreeHelper.GetChild(MyElementToSeek, i), FrameworkElement)
Dim Result = FindDescendant(OneChild, TypeToFind)
If Result IsNot Nothing Then Return Result
Next
Return Nothing
End Function
.
public FrameworkElement FindDescendant(FrameworkElement MyElementToSeek,
Type TypeToFind)
{
if (MyElementToSeek == null) return null;
if (MyElementToSeek.GetType() == TypeToFind) return MyElementToSeek;
for (i = 0;
(i<= (VisualTreeHelper.GetChildrenCount(MyElementToSeek) - 1)); i++)
{
object OneChild = TryCast(VisualTreeHelper.GetChild(MyElementToSeek, i),
FrameworkElement);
object Result = FindDescendant(OneChild, TypeToFind);
if (Result) return Result;
}
return null;
}
}
' MyScrollViewer = FindDescendant(MyListView, ScrollViewer)
Just off the top of my head, and I haven't tested this but could you do:
private void GetIndexes(ListView vv, out int startidx, out int count)
{
ListViewItem lvi1 = vv.GetItemAt(vv.ClientRectangle.X+6, vv.ClientRectangle.Y + 6);
ListViewItem lvi2 = vv.GetItemAt(vv.ClientRectangle.X+6, vv.ClientRectangle.Bottom-10);
startidx = vv.Items.IndexOf(lvi1);
int endidx = vv.Items.IndexOf(lvi2);
if (endidx == -1) endidx = vv.Items.Count;
count = endidx - startidx;
}
You could iterate through subsequent items, checking their visibility until you reach the one that isn't visible. This would give you a count of the visible items.
For example, something like:
for (int index = 0; index < list.Items.Count; index++)
{
if (list.ClientRectangle.IntersectsWith(item.GetBounds(ItemBoundsPortion.Entire)))
{
// Add to the list to get data.
}
else
{
// We got them all.
break;
}
}
I'm not sure what effect sorting would have on this though.
Have you seen the CacheVirtualItems event? The control will ask for a range of items instead of one-by-one. Tho, if scrolling, it still may ask for only one at a time. But pagedown/up will trigger the cache mechanism.
I know this post is old .....
Wrong
MyScrollViewer = FindDescendant(MyListView, ScrollViewer)
Right is:
Dim Myscrollviwer As ScrollViewer
Myscrollviwer = FindDescendant(myListView3, GetType(ScrollViewer))
MsgBox(Myscrollviwer.VerticalOffset)
foreach (var t in listView1.Items)
{
var lvitem = listView1.ItemContainerGenerator.ContainerFromItem(t) as ListViewItem;
if (lvitem == null) continue;
//lvitem will = null if it is not visible
// otherwise do stuff with lvitem such as:
lvitem.Foreground = Brushes.Green;
}
Try this:
If ListView.Items.Count > 0 Then
Dim lvi As ListViewItem = ListView.TopItem
If lvi Is Nothing Then Return
Dim startIndex As Integer = lvi.Index
Dim lastVisible As Integer = startIndex
While ListView.Items(lastVisible).Bounds.Bottom < Me.lvRes.Bounds.Bottom
lastVisible += 1
End While
lastVisible -= 1
End If

Categories