Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Display data from API, into WPF application.
Hello, Im creating an application for a questionnaire. It calls the data from the API and i would like to know what is the best way to display the information.
The information displayed will have to be "questionnaire type" and will be attempted by users and saved into database with the selected values.
Thanks
I already tried through textboxes that are dynamically created from a List, but setting the location of the textboxes tend to be full of errors
Please have a look at StackPanel
It stacks its child elements below or beside each other, dependening on its orientation.
With a stack panel you can place multiple elements atop of each other, see the sample from the link provided
<StackPanel>
<TextBlock Margin="10" FontSize="20">How do you like your coffee?</TextBlock>
<Button Margin="10">Black</Button>
<Button Margin="10">With milk</Button>
<Button Margin="10">Latte machiato</Button>
<Button Margin="10">Chappuchino</Button>
</StackPanel>
this will result in the following layout
You can create these dynamically. Take the following template
<StackLayout x:Name="QuestionStack">
<TextBlock Margin="10" FontSize="20" x:Name="QuestionTextBlock" />
</StackLayout>
and in your code behind
void DisplayQuestion(Question question)
{
QuestionTextBlock.Text = question.QuestionText;
foreach(var answer in question.Answers)
{
AddAnswerButton(answer);
}
}
private void AddAnswer(Answer answer)
{
QuestionStack.Children.Add(CreateButtonForAnswer(answer));
}
private Button CreateButtonForAnswer(Answer answer)
{
var button new Button()
{
Content = answer.Text,
Margin = 10
}
button.Click += (sender, eventArgs) =>
{
// handle button click
};
return button;
}
Please note: This is only one possibility. Without knowing more about your requirements it's hard to tell what you need exactly.
Edit:
Since you asked: You could for example create a custom control to display one question (I've replaced the Button with CheckBox and for sake of simplicity I've omitted the XAML, but it is not too hard to achieve the same results with XAML)
class QuestionControl : ContentControl
{
private Question question;
private StackLayout QuestionStackLayout { get; }
public QuestionControl()
{
QuestionStackLayout = new StackLayout();
QuestionTextBlock = new TextBlock()
{
Margin = 10,
FontSize = 20
};
QuestionStackLayout.Children.Add(QuestionTextBlock);
}
public Question Question
{
get
{
return question;
}
set
{
question = value;
DisplayQuestion();
}
}
private void DisplayQuestion()
{
QuestionTextBlock.Text = question.QuestionText;
foreach(var answer in question.Answers)
{
AddAnswerButton(answer);
}
}
private void AddAnswer(Answer answer)
{
QuestionStack.Children.Add(CreateButtonForAnswer(answer));
}
private CheckBox CreateCheckBoxForAnswer(Answer answer)
{
var checkBox new CheckBox()
{
Content = answer.Text,
Margin = 10
}
checkBox.Checked += (sender, eventArgs) =>
{
answer.IsSelected = (sender as CheckBox).IsChecked;
};
return checkBox;
}
}
You can now stack instances of QuestionControl. Since the Answer-objects are updated by the CheckBox.Click event you can simply access QuestionControl.Question to get which answers are selected. You might think about deep copying the Question when setting QuestionControl.Question instead of just setting the reference, to avoid side effects.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I'm trying to create a Xamarin App, where I can enter text in two entries and then after clicking the button, I want to display combination of the two entries on next page.
How to display labels in a list?
If you mean enter text in two labels is the enter text in two entrys . Here is a sample for reference :
PageA - Xaml :
<Entry x:Name="entryone"/>
<Entry x:Name="entrytwo"/>
<Button Text="Push" Clicked="Button_Clicked"/>
ContentPage - Button_Clicked :
private void Button_Clicked(object sender, EventArgs e)
{
SecondPage secondPage = new SecondPage();
secondPage.previousPageValue = entryone.Text + entrytwo.Text; //Set value to next page
Navigation.PushAsync(secondPage);
}
PageB - Xaml :
<Label x:Name="label"/>
ContentPage - show value when page OnAppearing ;
public partial class SecondPage : ContentPage
{
public string previousPageValue; //Declare here
public SecondPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
label.Text = previousPageValue;
}
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 3 years ago.
Improve this question
I need a ListView Renderer for Chat like whatsapp.
when if the new Message comes its automatically scroll down.
Please let me know if have a sample for this.
thanks
You don't need a custom renderer, you can just use a ListView and add some logic to do the scroll for you.
The View.xaml file:
<!-- Previous Implementation -->
<ListView x:Name="MessagesListView"
Grid.Row="0"
BackgroundColor="Transparent"
HasUnevenRows="True"
ItemTemplate="{StaticResource MessageTemplateSelector}"
ItemsSource="{Binding Messages}"
SelectionMode="None"
SeparatorVisibility="None" />
<!-- Remaining Implementation -->
The x:Name attribute is the important part, you're going to use that name in the code behind.
And now the View.xaml.cs file:
// Previous Implmentation
/// <summary>
/// Override of OnAppearing method. Fires as page is appearing.
/// Good place to set up event handlers.
/// </summary>
protected override void OnAppearing()
{
base.OnAppearing();
((INotifyCollectionChanged)MessagesListView.ItemsSource).CollectionChanged += OnListViewCollectionChanged;
}
/// <summary>
/// Override of OnDisappearing method. Fires as page is disappearing.
/// Good place to tear down event handlers.
/// </summary>
protected override void OnDisappearing()
{
base.OnDisappearing();
((INotifyCollectionChanged)MessagesListView.ItemsSource).CollectionChanged -= OnListViewCollectionChanged;
}
/// <summary>
/// Scrolls a the messages listview to the last item whenever
/// a new message is added to the collection.
/// </summary>
private void OnListViewCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
var myList = ((IEnumerable<Message>)MessagesListView.ItemsSource).ToList();
// Must be ran on main thread or Android chokes.
Device.BeginInvokeOnMainThread(async () =>
{
// For some reason Android requires a small delay or the scroll never happens.
await Task.Delay(50);
MessagesListView.ScrollTo(myList.Last(), ScrollToPosition.End, false);
});
}
// Remaining Implementation
Basically you're going to set an event to fire whenever the ListView's ItemSource changes. In that event, you're going to scroll to the end of the list.
You can achieve your requirement by scrolling the ListView to its last index after new item added into collection. To scroll the listview you can call LayoutManager.ScrollToRowIndex method by passing itemIndex.
private void InitializeSendCommand()
{
SendIcon = ImageSource.FromResource("SfListViewSample.Images.SendIcon.png", assembly);
NewText = "";
SendCommand = new Command(() =>
{
if (!string.IsNullOrWhiteSpace(NewText))
{
MessageInfo.Add(new MessageInfo
{
OutgoingMessageIndicator = ImageSource.FromResource("SfListViewSample.Images.OutgoingIndicatorImage.png", assembly),
Text = NewText,
TemplateType = TemplateType.OutGoingText,
DateTime = string.Format("{0:HH:mm}", DateTime.Now)
});
(ListView.LayoutManager asLinearLayout).ScrollToRowIndex(MessageInfo.Count - 1, Syncfusion.ListView.XForms.ScrollToPosition.Start);
}
NewText = null;
});
}
We have attached sample for your reference,
Sample Link:[http://www.syncfusion.com/downloads/support/directtrac/237037/ze/Sample2053309646][1]
Hope this helps.
Syncfusion Support Team
You need not a Custom Renderer for chat as a simple ListView will suffice.
Basically, you will bind the ItemsSource property to an ObservableCollection so when new messages are added, it will automatically appear on the listview.
Also, you might want to use Infinite Scrolling technique if there are significant number of historical chat messages that you believe user doesn't need/have to view them at once e.g. https://www.youtube.com/watch?v=DG5Asglf0vU
To scroll to the last message:
Device.BeginInvokeOnMainThread (() => {
Listviewname.scrollto(items[count-1], scrolltoposition.end, false)
});
});
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I need help for item add in the stackpanel.
My item name is "kanal" its wp8 imagebutton item.
Its my codes
public mainpage()
{
InitializeComponent();
foreach (var kanal in MainPage.kanalllarstatik)
{
mystackpanel.Children.Add(kanal);
}
}
I need add 130x130 pixel 3 button items per line like this:
Stackpanel only put one element per line so you need to put a horizontal stackpanel (in each line) and then add to it the three elements.
If you want a 130x130 control, you should use:
kanel.Height=130;
kanal.Width =130;
Code example
Test Data
List<Button> buttons = new List<Button>();
for (int i = 0; i < 16; i++)
{
buttons.Add(new Button
{
Height = 130,
Width = 130,
Content = new TextBlock
{
Text = i.ToString()
}
});
}
Algorithm
StackPanel horizontalStackPanel = new StackPanel
{
Orientation = Orientation.Horizontal
};
foreach (Button button in buttons)
{
horizontalStackPanel.Children.Add(button);
if (horizontalStackPanel.Children.Count == 3) //new line
{
myStackPanel.Children.Add(horizontalStackPanel);
horizontalStackPanel = new StackPanel
{
Orientation = Orientation.Horizontal
};
}
}
myStackPanel.Children.Add(horizontalStackPanel);
XAML
<StackPanel x:Name="myStackPanel"></StackPanel>
Result
I hope that this can help you.
I am writing an application to Windows Store, it will have exercises with questions which can be answered. I created a class Question where I have 2 variables question and answer.
Example of question:
Question q = new Question(
"This is simple [1] of question. This is the [2]",
new string[]
{
"sample",
"end"
});
What I want is to add questions to a grid view as a TextBlock with a question and a TextBox (the place where we will write the answer) in a place of [1] and [2]. So it would look like this:
<TextBox>
<TextBlock> This is simple </TextBlock>
<TextBox/>
<TextBlock> of question. This is the </TextBlock><TextBox/>
I'm not sure if I'm right to do it to look like that. Can I create a method in the Question class which adds items to MainPage.xaml in the way I presented?
I think you should make your own UserControl to display questions. The point is to create controls (TextBlock/TextBox) dynamically in code behind and add them as children to the WrapPanel. I can't see simple only-XAML decision here.
XAML:
<UserControl <!--skipped--> >
<WrapPanel x:Name="mainPanel">
</WrapPanel>
</UserControl>
Code behind:
partial class QuestionControl : UserControl
{
public QuestionControl()
{
InitializeComponent();
}
private Question _question = null;
public Question Question
{
get { return _question; }
set
{
_question = value;
UpdateUI();
}
}
private void UpdateUI()
{
mainPanel.Children.Clear();
if (this.Question != null)
{
List<FrameworkElement> controls = new List<FrameworkElement>();
string[] questionSegments = // some code to split question here
foreach (var qs in questionSegments)
{
controls.Add(new TextBlock() { Text = qs } );
}
for (int i = 0; i < this.Question.AnswerStrings.Length; i++)
{
string answer = this.Question.AnswerStrings[i];
TextBox newTextBox = new TextBox();
controls.Insert(i * 2 + 1, newTextBox); // inserting TextBoxes between TextBlocks
}
foreach (var control in controls)
{
mainPanel.Children.Add(control); // adding all the controls to the wrap panel
}
}
}
}
I am working on a little project for a contest in my city..and i just hit a brick wall.The thing is: i am creating a userControl in Blend(let's say a canvas,in wich i have a reactangle..a textblock and an image).My problem is that i can not add this to the listboxitem in WPF by code.Addin the userControl one by one in the designer seems to work..but the software is going to work with a variable number of items for the listbox.
private void mainPane1_Loaded(object sender, RoutedEventArgs e)
{
MessageBox.Show("layout updated");
questions cq;
Button btn;
for (int i = 1; i <= 10; i++)
{
btn = new Button();
btn.Content = "intreb" + i.ToString();
cq = new questions();
Canvas.SetZIndex(cq, 17);
//cq.questionHolder.Text = "intrebare" + i.ToString();
listaintrebari.Items.Add(cq);
MessageBox.Show("intrebare" + i.ToString());
listaintrebari.Items.Add(btn);
//MessageBox.Show("layout updated");
}
}
questions is my UserControl and listaintrebari is the listbox.I tried to add some buttons and it works great...but it seems to hate my userControl.
I am waiting for your thoughts on how to resolve this issue, and if you have any sugestions on what other is best to use in my situation and how..it would be great.Thank you!
Ok, here's some actual code that might help you out.
I will be using several WPF concepts that you might want to study further : DataBinding, DataTemplates, ImageSources, ObservableCollections
First you need to create (if you don't have it yet) an underlying class for your Questions. The simplest you can get would be something like this :
internal class Question
{
public ImageSource QuestionImage { get; set; }
public string QuestionText { get; set; }
}
Then in your screen's code behind (yes, we are not at MVVM yet), you should create an ObservableCollection of Question and pouplate them with your questions
I have smth like this:
public ObservableCollection<Question> Questions { get; private set; }
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
Questions = new ObservableCollection<Question>();
for (int i = 1; i <= 10; i++)
{
var newQ = new Question { QuestionText = "intrebarea " + i.ToString(), QuestionImage = _get your image as a ImageSource here_ };
Questions.Add(newQ);
}
}
The this.DataContext = this is very important, otherwise your Data Binding will not work.
In your design area, create a list and bind it to the Questions collection you created. The way the question is displayed in the list is driven by the "ItemTemlpate" as below.
<ListBox ItemsSource="{Binding Questions}">
<ListBox.ItemTemplate>
<StackPanel>
<Image Source="{Binding QuestionImage}" Height="20" Width="20"/>
<TextBlock Margin="5" Text="{Binding QuestionText}" />
</StackPanel>
</ListBox.ItemTemplate>
</ListBox>
You can replace the I have there with your UserControl contents or event the UserControl itself, but make sure to preserve the Bindings to the objects in your Question class.
Like I said above, many things might not make sense at this point so make sure you read about them : What is a data Binding, What is a DataContext, What is an ObservableCollection. Also, try looking at MVVM when you get a chance...
Lastly, if you are unsure how to get an ImageSource when you have a jpg or png file in your project:
public ImageSource GetImagesource(string location)
{
var res = new BitmapImage()
res.BeginInit();
res.UriSource = new Uri("pack://application:,,,/ApplicationName;component/" + location);
res.EndInit();
return res;
}
The right way to handle this kind of situation is by having a data model with a collection of your questions. Then bind your ListBox.ItemsSource to the collection and provide a DataTemplate that uses your UserControl.
Use the ListBox's ItemTemplate to define what you want each instance of your object to look like, then bind the ListBox's ItemsSource to a collection of that type.
You need to create a collection (e.g. List) of your control and bind the collection to the ListBox.