Set value (int) to checke radio button wpf - c#

Hope you can help me whit this :)
I WANT TO: give the following values to four different radio buttons: 30, 50, 100 and 200 (doesn't really matter what the values is for now). Right now I need to go into the code and change the number my self. I want these radio buttons to do the job when checked.
I will paste the code here. Can you please be very spesific when explaining this to me (if you can and bother to do so).
Thank you!
//Method for establishing connection to database.
// Sette parameter for limit
public static MongoDatabase GetDatabase(string searchText)
{
/* try
{*/
TweetOC.Clear();
MongoServerSettings settings = new MongoServerSettings();
settings.Server = new MongoServerAddress("xxxx", xxxx);
MongoServer server = new MongoServer(settings);
MongoDatabase database = server.GetDatabase("tweet_database");
var collection = database.GetCollection<Tweets>("docs");
System.Console.WriteLine("5");
var query = Query.And(Query.Matches("text", searchText),
Query.NE("geo_enabled", false));
System.Console.WriteLine("6");
//var match = Query.ElemMatch("text", query);
var cursor = collection.Find(query);
cursor.SetLimit(30);
System.Console.WriteLine("7");
//Puts the result from the last query into a list.
var resultList = cursor.ToList();
//Iterates over the previous mentioned list and inserts the content into the ObservableCollcetion created earlier.
foreach (var item in resultList)
TweetOC.Add(item);
System.Console.WriteLine(TweetOC.Count);
return database;
}
I HAVE TO CHANGE CURSOR.LIMIT(manually) ALL THE TIME. I WANT THIS NUMBER TO CHANGE AUTOMATICALLY WHEN A RADIO BUTTON IS CHECKED.
THE METHOD AND XAML WILL FOLLOW:
// I want this to be if radiobutton is 20, then this should be sent to cursor.set limit. I cannot make another string in database.cs without getting an error.
/* Private void RadioButton_Checked(object sender, RoutedEventArgs e)
{
var radioButton = sender as RadioButton;
if (radioButton == 20)
return;
int intIndex = Convert.ToInt32(radioButton.Content.ToString(Cursor.SetLimit));
}
* Remember Checked="RadioButton_Checked" in the XAML if you want to try
*/
XAML for one of the four buttons:
<RadioButton Content="RadioButton" Grid.Column="2" HorizontalAlignment="Left"
Margin="20,116,0,0" Grid.Row="2" VerticalAlignment="Top"/>
HOW SHOULD THIS ACTUALLY LOOK TO GET IT WORKING? PLEASE EDIT THE CODE (if you bother) SO I CAN SEE AND UNDERSTAND THIS.
THANKS AGAIN!

To do this in an MVVM friendly way, bind the IsChecked property like this:
IsChecked="{Binding Path=CursorLimit, Converter={StaticResource ParamToIntConverter}, ConverterParameter=10}"
Set the parameter to the correct value for the given radio button, of course. If you are not familiar with converters, you need a line in your resources like (assuming you have the local xmlns set up to point to the converter namespace):
<local:ParamToIntConverter x:Key="ParamToIntConverter"/>
Then your converter looks like:
public class ParamToIntConverter : IValueConverter
{
public object Convert (...)
{
return value.Equals(int.Parse((string)parameter));
}
public object ConvertBack(...)
{
if ((bool)value)
return int.Parse((string)parameter);
else
return Binding.DoNothing;
}
}

Your xmal code:
<RadioButton Content="RadioButton" Grid.Column="2" HorizontalAlignment="Left"
Margin="20,116,0,0" Grid.Row="2" VerticalAlignment="Top" Checked="RadioButton_Checked" />
Your *.cs code:
private void RadioButton_Checked(object sender, RoutedEventArgs e)
{
// ... do what you need for this button
}
Use different Checked="[insert_method_name]" template with equal method names in your *.cs file and do what you need in each method.
Also you can try to make it as in this http://www.dotnetperls.com/radiobutton-wpf example.

Related

Access XAML binding in code-behind

I am working in Xamarin but I believe this applies to any UWP application using XAML.
First I have two ContentPages. On the first page, I want to pass some data to the second page, so I do this as part of the navigation:
async void BuyTickets(object sender, EventArgs e)
{
var ticketOrderTotal = new TicketOrder
{
OrderTotal = lblOrderAmount.Text,
OrderTotalList = ticketsPrices.Where(o => o.TicketQuantity > 0).ToList<Ticket>()
};
var paymentPage = new PaymentPage();
paymentPage.BindingContext = ticketOrderTotal;
await Navigation.PushAsync(paymentPage);
}
The above works fine in XAML. On the second page (PaymentPage), I am able to reference the BindingContext like this, for example, and the Text property is correct:
<Label x:Name="lblOrderAmount" Text="{Binding OrderTotal}" />
What I would like to do is access the "{Binding OrderTotal}" value in the C# code-behind of the second page. I found a way to do this, too, but it just does not seem optimal. This is the kludge I have in place:
<Label x:Name="lblOrderAmount" Text="{Binding OrderTotal}" BindingContextChanged="GetChargeAmount" />
And this is the code-behind for the label:
public static string m_charge_amount = "";
...
private void GetChargeAmount(object sender, EventArgs e)
{
var lbl = ((Label)sender);
m_charge_amount = lbl.Text;
}
So my question is this: is there a better way to do this? It is particularly hard to research as XAML seems to be rooted in WPF, Silverlight, Xamarin, Windows 8, and now Windows 10 (UWP). It is all over the place. I am constantly fighting with the framework to do things that I think should be quite easy to do....like this. Please help but do be nice.
Thank you.
EDIT:
Per #Jason's comment, you can pass an object to the page constructor, and that will work. This is what the re-worked function looks like now:
async void BuyTickets(object sender, EventArgs e)
{
var ticketOrderTotal = new TicketOrder
{
OrderTotal = lblOrderAmount.Text,
OrderTotalList = ticketsPrices.Where(o => o.TicketQuantity > 0).ToList<Ticket>()
};
var paymentPage = new PaymentPage(ticketOrderTotal);
paymentPage.BindingContext = ticketOrderTotal;
await Navigation.PushAsync(paymentPage);
}
And then the result from debugging:
instead of having PageA set PageB's BindingContext, instead pass the ticketOrderTotal object as a parameter on PageB's constructor. Then PageB can set it's own BindingContext as well as keep a local reference to the ticketOrderTotal object.

Unable to add text suggestion from a file to my textbox in C#

I am making a Universal Windows App, which includes inserting text into a textbox. I want my app to suggest text from a file to insert to the textbox. But I could not find that property. I have added the textbox in the MainPage.xaml through XAML tags. I believe there is a property for this operation in WPF API. I am just not sure if I can do this in UWP.
I recommend using the AutoSuggestBox control for UWP. The auto-suggest results list populates automatically once the user starts to enter text. The results list can appear above or below the text entry box.
<AutoSuggestBox PlaceholderText="Search" QueryIcon="Find" Width="200"
TextChanged="AutoSuggestBox_TextChanged"
QuerySubmitted="AutoSuggestBox_QuerySubmitted"
SuggestionChosen="AutoSuggestBox_SuggestionChosen"/>
private void AutoSuggestBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{
// Only get results when it was a user typing,
// otherwise assume the value got filled in by TextMemberPath
// or the handler for SuggestionChosen.
if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
{
//Set the ItemsSource to be your filtered dataset
//sender.ItemsSource = dataset;
}
}
private void AutoSuggestBox_SuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
{
// Set sender.Text. You can use args.SelectedItem to build your text string.
}
private void AutoSuggestBox_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
{
if (args.ChosenSuggestion != null)
{
// User selected an item from the suggestion list, take an action on it here.
}
else
{
// Use args.QueryText to determine what to do.
}
}
Here is the link to the GitHub repo for a complete UI basics sample.
Hope this helps.
This may not apply for UAP but with WPF there's a trick that allows a "dropdown suggestion list". You can replace text box with a combobox and populate it's items when user types. This can be achieved by doing bindings like so:
Text={ Binding Path=meCurrentValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged }
ItemsSource={Binding Path=meFilteredListOfSuggestions, Mode=TwoWay }
Then within your viewmodel you can simply do:
public string meCurrentValue
{
get { return _mecurrentvalue; }
set {
_mecurrentvalue = value;
updateSuggestionsList();
NotifyPropertyChanged("meCurrentValue");
NotifyPropertyChanged("meFilteredListOfSuggestions"); // notify that the list was updated
ComboBox.Open(); // use to open the combobox list
}
public List<string> meFilteredListOfSuggestions
{
get{return SuggestionsList.Select( e => e.text.StartsWith(_mecurrentvalue));}
}
EDIT:
Remember to set the editable value of the combobox to TRUE, this way it will act like a normal textbox.

One property for multiple buttons

Is there a way to write in c# one property for multiple items. e.g. i have 5 buttons, i don't want to write button1.text = "etc", button2.text = "etc, I want to write button.text="etc" and have button1.text through button5.text to have "etc" text.
I guess this is feasible with something similar to:
public void SetButtonText(string value) {
this.Controls.OfType<Button>().ToList().ForEach(b => b.Text = value);
}
Or the same through a property:
public string ButtonText {
set {
Controls
.OfType<Button>()
.ToList()
.ForEach(b => b.Text = value);
}
}
EDIT
After a further research, I found out that there are no direct way to access the controls of a page in Windows Phone as I know. So it all depends on whether you wish to get down from the PhoneApplicationPage:
As I see it, your solution revolves around the Page.LogicalChildren Property.
public class MyPage : Page {
public string ButtonText {
set {
LogicalChildren
.OfType<Button>()
.ToList()
.ForEach(b => b.Text = value);
}
}
}
Since the LogicalChildren has a protected accessor, you need to access it through a derived class, which shall be convenient for any kind of page you're working on Windows Phone, I guess.
Or drop a Grid right onto the PhoneApplicationPage and then drop other controls over it such as your buttons, then you shall access them through the Grid.Children property.
So, having dropped your Grid and naming it myBaseGrid, one would do the following:
public void SetButtonsText(string text) {
myBaseGrid.Children
.OfType<Button>()
.ToList()
.ForEach(b => b.Text = "myText");
}
I would personally go with the method which name makes it clear what you're doing by spelling the word Button in plural as in my sample.
Perhaps you are looking for control arrays: http://msdn.microsoft.com/en-us/library/aa289500(v=vs.71).aspx?
You can't assign all 5 buttons to the same reference, so that button.text = "etc" will work.
You can however, bind the buttons to the same property:
<Button Content="{Binding myText}"/>
<Button Content="{Binding myText}"/>
<Button Content="{Binding myText}"/>
<Button Content="{Binding myText}"/>
If the binding is set properly with INotifyPropertyChanged, then all will update when myText is updated.
You could also put the controls into a collection and foreach over them to set their Content property as others have suggested.
One way would be to create a method that sets them all for you, which you would have to manually write once:
public void SetAllButtonTexts(string text)
{
button1.text = text;
button2.text = text;
// . . .
}
Alternatively you could use a loop:
public void SetAllButtonTexts(string btnText)
{
foreach (var control in this.Controls.OfType<Button>())
{
(control).Text = btnText;
}
}
And if you don't want to update ALL the buttons, one easy but not-so-elegant thing you could do is modify the Tag property of the buttons you want to change with some custom text, and only update those:
public void SetAllButtonTexts(string btnText, string tagText = "")
{
foreach (var control in this.Controls.OfType<Button>()
.Where(b => string.IsNullOrEmpty(tagText)
|| (b.Tag != null && b.Tag.Equals(tagText))))
{
(control).Text = btnText;
}
}
In a few words: Group up all your buttons which should get changed in a list. Then later loop through this list and set your text of all buttons.
Here's some code.
First of all:
public static List<Button> buttonList = new List<Button>{};
On form_load:
buttonList.AddRange(new List<Button>{ button1,button2,button3,...}); // Group your buttons
Now it depends on 'when' or 'where' you want to change it. If the buttons should be changed right in the beginning, put the following code into the form_load-event. Else when it should be fired on an event, place it into an event.
foreach(Button btn in buttonList)
{
btn.Text = "Change all button-texts from list at one time.";
}
You can also handle multiple lables or boxes etc. like this. Just declare the right datatype.
Greetings

How to control DynamicResource implementation in C#

In my program I would like to implement a DynamicResource from code-behind. Right now I am binding the Content of a Label to a string property in my Data Model...
<Label Content="{Binding DataModel.StringValue}" ... />
Following this question, I have implemented the string in my Data Model like so:
private string _stringValue = (string)Application.Current.Resources["nameOfResource"];
public string StringValue
{
get { return _cartsInSystem; }
set
{
_cartsInSystem = value;
NotifyPropertyChange(() => CartsInSystem);
}
}
I would like to make it so that every time the user changes the Resource Dictionary, this string value updates with the new value.
I am trying to achieve the same effect as something like this:
<Label Content="{DynamicResource nameOfResource}" ... />
Please let me know what I am doing wrong, and how I might correctly implement something like this.
UPDATE 1: As requested by #HighCore, this is an example of my code where I only have access to string values from code-Behind (or C# class)
(This is part of a ViewModel of a TreeView in my MainWindow)
//The "DisplayNames" for these nodes are created here and not accessible through xaml.
//This is because the xaml window has access to this code through it's itemsSource
private HierarchicalVM CreateCartsNode()
{
return new HierarchicalVM()
{
DisplayName = "Carts",
Children =
{
new CartConnection() { ConnectionDataModel = new CartConnectionModel(), DisplayName = "Cart Connection" },
new HierarchicalVM() {
DisplayName = "Cart Types",
Children = {
CreateCartType( new CartConfigModel() { DisplayName = "Default" }, new CartIO_Model() ),
},
Commands = { new Command(OpenAddCart) {DisplayName = "Add..."} }
}
}
};
}
This is the xaml of the above TreeView:
<!-- Tree view items & Functions -->
<TreeView ItemsSource="{Binding DataTree.Data}" ... />
Update 2: I have another perfect example of my problem...
I have a comboBox that has it's itemsSource bound to an ObservableCollection in my Data Model. Like so:
private ObservableCollection<string> _objCollection;
private string _notUsed = "Not Used";
private string _stop = "Stop";
private string _slow = "Slow";
public DataModel()
{
ObjCollection = new ObservableCollection<string>() { _notUsed, _stop, _slow };
}
public ObservableCollection<string> ObjCollection {...}
xaml:
<ComboBox ItemsSource="{Binding DataModel.ObjCollection}" ... />
If I want to make it so that the items in this comboBox change when the resource dictionary is changed, it looks like I'll need to handle it in C# rather than xaml.
After OP's UPDATE 2 and having a chat with him for a different question, I understood he was trying achieve localisation for his application. He would change Resource Dictionaries (for different languages) on the fly, and he wanted his C# code re-read/load values from Application.Current.Resources.
APPROACH ONE
After you changing the Resource Dictionary, You could use something like EventAggregator/Mediator to let other parts of the application (including ViewModels) know about Resource Dictionary change, and they respond to it by re-loading/reading resources/values from Application.Current.Resources
APPROACH TWO
OP doesn't want to introduce any new dependencies like EventAggregator/Mediator. So, I suggested this second approach. I know, it is not pretty, but here it goes..
You could have a global static event instead of EventAggregator/Mediaotr to let other parts of the application know that you swapped resource dictionary, and they will re-load/read values.
Read this answer about potential problems with static events and their subscriptions.

Silverlight 3 AutocompleteBox.text is not updated

In silverlight 3 I am doing something like :
//currentDataForm.itemssource = currentCollisionDisplay;
//<input:AutoCompleteBox Width="74" x:Name="InvolvedCnt" Text="{Binding involvedCnt, Mode=TwoWay}"
...
for (int i = 0; i < driverNums; i++)
{
AddCollisionVehicle_Click(null, null);
}
...
private void AddCollisionVehicle_Click(object sender, RoutedEventArgs e)
{
currentCollisionDisplay.involvedCnt ++;
(df_collision.FindNameInContent("InvolvedCnt") as AutoCompleteBox).Text = currentCollisionDisplay.involvedCnt.ToString();
(df_collision.FindNameInContent("InvolvedCnt") as AutoCompleteBox).UpdateLayout();
string testString = (df_collision.FindNameInContent("InvolvedCnt") as AutoCompleteBox).Text;
}
so the initial value of the autocompletebox is "1".
if driverNums = 1 then the autocompletebox.text is 2.. which is correct
but if driverNums = 2 then the autocompletebox.text is 2.. which is wrong.
I changed the autocompletebox text field within an array, but this is not updated properly.. does anybody know how to fix this issue?
Strange thing is if i check testString variable, the value is correct..
This appears to be a known issue. See http://forums.silverlight.net/forums/p/199616/519232.aspx
A workaround that worked in my application is to clear out the Text property and then set it again using Dispatcher.BeginInvoke, i.e. something like this:
autoCompleteBox.Text = null;
Dispatcher.BeginInvoke(() =>
autoCompleteBox.Text = currentCollisionDisplay.involvedCnt.ToString());
I've only done this in one scenario so I don't know for sure if it'll work for you. My application also used bindings (I called ClearValue and then SetBinding).
You need to use the method "ValueMemberBrinding"
<toolkit:AutoCompleteBox x:Name="InvolvedCnt" ValueMemberBinding="{Binding Name}"/>

Categories