I am working on silverlight using c#. I have to display the combo items in a scrollbar.
My attempt to do this is:
TextBlock txtblkName = generateTextBlock();
ComboBox cb = new ComboBox();
ScrollViewer scrollViewer = new ScrollViewer();
cb.Width = 45;
cb.Height = 20;
foreach (String item in param.Component.Attributes.Items)
cb.ItemsSource = param.Component.Attributes.Items;
scrollViewer.Content = cb;
scrollViewer.HorizontalAlignment = HorizontalAlignment.Center;
scrollViewer.VerticalAlignment = VerticalAlignment.Center;
scrollViewer.ScrollToVerticalOffset(3);
cb.SelectionChanged += (o, e) =>
{
txtblkName.Text = cb.SelectedValue.ToString() + " " + param.Unit;
};
cb.SelectedIndex = param.Component.Attributes.Selected != -1 ? param.Component.Attributes.Selected : 0;
Grid.SetColumn(scrollViewer, 1);
childGrid.Children.Add(scrollViewer);
which results in scroll over combo box .Like this:
Not on it's item displayed by scrollbar.
Could some one please help me to create scrollbar only on items displayed not on all combo box?
You dont need ScrollViewer here, If you need Scrollbar for your comboboxItems set this property MaxDropDownHeight to some value
ComboBox cb = new ComboBox();
List<string> items = new List<string>();
items.Add("1");
items.Add("2");
items.Add("3");
items.Add("5");
items.Add("7");
items.Add("8");
cb.ItemsSource = items;
cb.MaxDropDownHeight = 20;
childGrid.Children.Add(cb);
Related
I want to sort a list that contains custom control.
The list has a list of listboxitem that have content with a checkbox inside, and the checkbox has a textblock inside.
List<ListBoxItem> listboxItem =new List<ListBoxItem>();
Some code that add the control into listboxItem with for loop
{
ListBoxItem lbi = new ListBoxItem();
CheckBox chkBox = new CheckBox();
TextBlock txtBlock = new TextBlock();
txtBlock.Text = sometext;
chkBox.Content = txtBlock;
lbi.Content = chkBox;
listBoxItems.Add(lbi);
}
listboxItems.Sort();
And I have implement IComparable interface
public int CompareTo(Object obj)
{
if (obj == null) return 1;
List<ListBoxItem> listBoxItems = obj as List<ListBoxItem>;
for (int i = 0; i < listBoxItems.Count; i++)
{
if (i < listBoxItems.Count)
{
ListBoxItem listBoxItem = listBoxItems[i];
ListBoxItem lbi = this.listBoxItems[i];
CheckBox checkBox = listBoxItem.Content as CheckBox;
CheckBox chk = lbi.Content as CheckBox;
TextBlock textBlock = checkBox.Content as TextBlock;
TextBlock txt = chk.Content as TextBlock;
return string.Compare(txt.Text, textBlock.Text);
}
}
return 0;
}
And it still give me error that need to implement Icomparable.
Not sure is it implement or use correctly, pretty new to me for this implementation #.#
Just found out that can use Linq and Tag to get rid of IComparable.
Edited Code:
Some code that add the control into listboxItem with for loop
{
ListBoxItem lbi = new ListBoxItem();
CheckBox chkBox = new CheckBox();
TextBlock txtBlock = new TextBlock();
txtBlock.Text = sometext;
chkBox.Content = txtBlock;
lbi.Content = chkBox;
lbi.Tag = sometext;
listBoxItems.Add(lbi);
}
listBoxItems = listBoxItems.OrderBy(x => x.Tag).ToList();
Then, the list will be sort in alphabetic perfectly.
I have an application where i will need to add dynamic controls to a panel
based on the value of a number entered in a textbox.
E.g 5 means i generate 5 rows of the controls on the button click event.
The issue is that when a large number (for example 50) is entered,although
50 rows of dynamic controls are added,i am unable to scroll down to each
of the 50 rows.
private void button1_Click(object sender, EventArgs e)
{
int inputNumber = Int32.Parse(textBox1.Text);
int wid=0;
int hgt = 0;
for (int i = 1; i <= inputNumber; i++)
{
//Create a new label and text box
Label labelInput = new Label();
TextBox textBoxNewInput = new TextBox();
ComboBox cb = new ComboBox();
//Initialize label's property
labelInput.Text = "Input " + i;
labelInput.Location = new Point(30, textBox1.Bottom + (i * 30));
labelInput.AutoSize = true;
//Initialize textBoxes Property
textBoxNewInput.Location = new Point(labelInput.Width, labelInput.Top - 3);
cb.Location = new Point(textBoxNewInput.Width + labelInput.Width + 10, textBoxNewInput.Top);
hgt += textBoxNewInput.Top;
//Add the labels and text box to the form
panel1.Controls.Add(labelInput);
panel1.Controls.Add(textBoxNewInput);
panel1.Controls.Add(cb);
}
ScrollBar vScrollBar1 = new VScrollBar();
vScrollBar1.Dock = DockStyle.Right;
vScrollBar1.Scroll += (mender, f) => { panel1.VerticalScroll.Value = vScrollBar1.Value; };
panel1.Controls.Add(vScrollBar1);
Controls.Add(panel1);
}
How can i be able to scroll from row 1 to row 100 or row 500 as the case may be?
Thanks
Not sure why you're not using a grid? Manipulate the grid instead.
I did further research and i got the answer:
I removed these lines of code
ScrollBar vScrollBar1 = new VScrollBar();
vScrollBar1.Dock = DockStyle.Right;
vScrollBar1.Scroll += (mender, f) => { panel1.VerticalScroll.Value = vScrollBar1.Value; };
panel1.Controls.Add(vScrollBar1);
And i just set the autoscroll property
panel1.AutoScroll=true;
Works fine
I am Silverlight developer and coding in C# to select an item from a list and display the selected item in the textBlock nearby.
My code to do so is:
ListBox lines = new ListBox();
TextBlock txtblkShowSelectedValue = new TextBlock();
ScrollViewer scrollViewer = new ScrollViewer();
scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
lines.ItemsSource = param.Component.Attributes.Items;
Grid.SetColumn(lines, 1);
Grid.SetRow(lines, LoopCount);
childGrid.Children.Add(lines);
lines.SelectedIndex = 0;
lines.SelectedItem = param.Component.Attributes.Items;
The problem is how to select a value and how to display it in textblock "txtblkShowSelectedValue " ? because I cannot declare textblock and List variable globally because of current condition if I use selectionChange event
EDIT: The current scenario is :(lines (List) is in different function so it's not in scope of List_SelectionChanged() function)
private static Grid GenerateList(Parameter param, int LoopCount, Grid g)
{
Grid childGrid = new Grid();
ColumnDefinition colDef1 = new ColumnDefinition();
ColumnDefinition colDef2 = new ColumnDefinition();
ColumnDefinition colDef3 = new ColumnDefinition();
childGrid.ColumnDefinitions.Add(colDef1);
childGrid.ColumnDefinitions.Add(colDef2);
childGrid.ColumnDefinitions.Add(colDef3);
TextBlock txtblk1ShowStatus = new TextBlock();
TextBlock txtblkLabel = new TextBlock();
ListBox lines = new ListBox();
ScrollViewer scrollViewer = new ScrollViewer();
scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
lines.ItemsSource = param.Component.Attributes.Items;
Grid.SetColumn(lines, 1);
Grid.SetRow(lines, LoopCount);
childGrid.Children.Add(lines);
lines.SelectedIndex = 0;
lines.SelectedItem = param.Component.Attributes.Items;
lines.SelectionChanged += new SelectionChangedEventHandler(List_SelectionChanged);
lines.SelectedIndex = lines.Items.Count - 1;
g.Children.Add(childGrid);
return (g);
}
static void List_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
MessageBox.Show("clist _SelectionChanged1");
TextBlock txtblk1ShowStatus = new TextBlock();
txtblk1ShowStatus.Text = lines[(sender as ListBox).SelectedIndex];
}
This could be streamlined, but should work as a quick 'n dirty example of one way to solve the problem...
void lb_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Grid g = null;
ListBox lb = sender as ListBox;
if (lb != null && lb.SelectedIndex >= 0)
{
// Find the top-level grid
var parent = VisualTreeHelper.GetParent(lb);
while (parent != null)
{
if (parent.GetType() == typeof(Grid))
{
if ((parent as Grid).Name.Equals("LayoutRoot"))
{
g = (Grid)parent;
break;
}
}
parent = VisualTreeHelper.GetParent(parent);
}
// Found the LayoutRoot, find the textblock
if (g != null)
{
for (int i = 0; i < g.Children.Count; i++)
{
var child = VisualTreeHelper.GetChild(g, i);
if (child is TextBlock)
{
(child as TextBlock).Text = (string)lb.SelectedItem;
break;
}
}
}
}
}
You could also name your textblock and search for that (as I did for "LayoutRoot").
Obviously, this code assumes the textblock is a child of the top-level Grid. Implementing a recursive search wouldn't be difficult.
lines.SelectionChanged+=new System.EventHandler(this.UpdateTextBlock); // add selectionchanged even for your listbox;
private void UpdateTextBlock(object sender, SelectionChangedEventArgs e)
{
txtblkShowSelectedValue.Text=this.lines[(sender as Listbox).SelectedIndex].ToString(); // just edit the content of your texblock
}
EDIT : thank you, and sorry to be late :-)
try this :
add parameter for the function, as this :
lines.SelectionChanged += new SelectionChangedEventHandler(List_SelectionChanged)
change parameter of this function and set your textblock as this :
static void List_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
MessageBox.Show("clist _SelectionChanged1");
txtblkShowSelectedValue.Text=this.lines[(sender as Listbox).SelectedIndex].ToString()
}
Afteralli solved the problem like this:
lines.SelectionChanged += (o, e) =>
{
MessageBox.Show("clist _SelectionChanged1");
txtblk1ShowStatus.Text = lines.SelectedItem.ToString();
};
lines.SelectedIndex = lines.Items.Count - 1;
in my function GenerateList(..)
I am new to windows phone. I am trying to make pivot of questions . I want to add a text block and 2 radio buttons on each pivot item . I managed to add the textbook but didn't know how to add radio buttons.
var count = i + 1;
var textblok = new TextBlock { Text = o["questions"][i]["question"].ToString(), FontSize = 20,Width=450};
textblok.TextWrapping = TextWrapping.Wrap;
quizPivot.Items.Add(new PivotItem { Name="question"+count, Header = "Question " + count, Content = textblok,});
after adding container
for (var i = 0; i < Globals.quizcount; i++)
{
var count = i + 1;
var stackpanel = new StackPanel();
var textblok = new TextBlock { Text = o["questions"][i]["question"].ToString(), FontSize = 20,Width=450};
textblok.TextWrapping = TextWrapping.Wrap;
stackpanel.Children.Add(textblok);
var radio = new RadioButton { Name = "useransYes", Content = "Yes" };
stackpanel.Children.Add(radio);
var radio1 = new RadioButton { Name = "useransNo", Content = "No" };
stackpanel.Children.Add(radio1);
//, HorizontalAlignment = "Left", Margin = "66,317,0,0", VerticalAlignment = "Top
quizPivot.Items.Add(new PivotItem { Name = "question" + count, Header = "Question " + count, Content = stackpanel });
quesId.Text = o["questions"][i]["_id"].ToString();
}
2nd i want to know how to get all the pivot items i mean the contents in it.
Thanks
You need to use a container control to add multiple UI controls to single PivotItem. For example using StackPanel as container :
//create the container
var stackpanel = new StackPanel();
//create textblock
var textblok = new TextBlock { Text = o["questions"][i]["question"].ToString(), FontSize = 20,Width=450};
textblok.TextWrapping = TextWrapping.Wrap;
//add to container
stackpanel.Children.Add(textblok);
//create radiobutton
var radiobutton = new RadioButton{Content = "Radio Button content"}
//add to container
stackpanel.Children.Add(radiobutton);
//add the container as content of pivot item
quizPivot.Items.Add(new PivotItem { Name="question"+count, Header = "Question " + count, Content = stackpanel,});
Anyway, there is another way around to accomplish this with much cleaner approach. Avoid creating UI controls from code by using data-binding and templating pivot item.
I have the following code where a click event will dynamically create additional Canvas to the WrapPanel, and each Canvas contains a TextBox and a Button. Once the Button on one Canvas is click, TextBox.Text and Button.Content change from "Foo" to "Jesus".
The below code works, but it's not ideal. Because each property Change ("Foo" to "Jesus), I have to run a loop. I have to run two loops just to change the text on the TextBox and Button. Is there a direct way to change the Properties other then a Loop? My actually application contains 30+ controls in a Canvas, I don't want to run 30+ loops each time just to change some text.
List<Canvas> cvList = new List<Canvas>();
List<TextBox> tbList = new List<TextBox>();
List<Button> FooList = new List<Button>();
WrapPanel wp = new WrapPanel();
private void createbtn1_Click(object sender, RoutedEventArgs e)
{
Canvas cv = new Canvas();
StackPanel sp = new StackPanel();
TextBox tb = new TextBox();
Button Foo = new Button();
sp.Orientation = Orientation.Vertical;
sp.Children.Add(tb);
sp.Children.Add(Foo);
cv.Children.Add(sp);
wp.Children.Add(cv);
cvList.Add(cv);
tbList.Add(tb);
FooList.Add(Foo);
cv.Width = 100;
cv.Height = 100;
tb.Text = "#" + (cvList.IndexOf(cv)+1);
tb.Width = 50;
tb.Height = 30;
Foo.Content = "Foo";
Foo.Click += destroy_Click;
}
private void Foo_Click(object sender, RoutedEventArgs e)
{
Button b = sender as Button;
var bIndex = FooList.IndexOf(b);
foreach (TextBox t in tbList)
{
if (tbList.IndexOf(t) == bIndex)
{
t.Text = "Jesus";
}
}
foreach (Button f in FooList)
{
if (FooList.IndexOf(t) == bIndex)
{
t.Content = "Jesus";
}
}
}
Just access the text boxes by index and set the content of the button directly:
if(bIndex < tbList.Count && bIndex != -1)
tbList[bIndex].Text = "Jesus";
if(b != null && bIndex != -1)
b.Content = "Jesus";
why can't you just get the item at the index and set that items text:
tbList[bindex].Text="Jesus";
As for setting the buttons content, you already have the button from the click event, so just use that:
b.Content = "Jesus";
You current code just loops through each item in the list and gets the index of the item and sees if it is the index you want. Accessing by the indexer of the list directly will give you what you want.
You will probably want to do some error checking, but that is not currently done in your existing code either.
Some info on using indexers from MSDN