How to current logged in user's id to textbox - c#

Im trying to get data from first row in datagrid in c# wpf app but i cannot figure out the code.
Can somebody help me?
I tried WF app code but it doesn't work because there's not function of .Rows
return Convert.ToInt32(dataGridView1.Rows[dataGridView1.CurrentRow.Index]
.Cells[0].Value.ToString());
Thanks
UPDATE:
Im trying to get current's logged in users id to display in textbox, so i can use it to make a reservation later and join two tables.
Also can somebody help write SQL statement that joins two different id's (user's ID and id of the book that user is buying into a new table called "reservations"
Can somebody help me?

Since others have already posted a potential workaround for your problem, I'll go ahead and explain the proper solution:
Delete all your code and start all over.
WPF is NOT winforms, and if you're working with WPF, you need to leave behind any and all notions you got from the traditional approach and understand and embrace The WPF Mentality.
Basically, you don't "get data from a DataGrid" in WPF, simply because UI is NOT Data.
This means that the data you're trying to obtain must not be stored by the UI to begin with. Instead, you need to create a proper Data Model and use DataBinding to populate the UI with such data from the DataModel.
The responsibility of the UI is to show data, not store it. This is an important mindshift from the traditional approach where you would manually populate the UI with data and then retrieve the data from the UI.
WPF Two-way DataBinding capabilities make it easier to implement such scenarios in a clean, decoupled way.
Say you have a User class which has a Name and an Id property:
public class User
{
public int Id {get;set;}
public string Name {get;set;}
}
first step to show this in a DataGrid is to create a proper ViewModel that contains a collection of this class:
public class ViewModel
{
public ObservableCollection<User> Users {get; private set;}
public ViewModel()
{
Users = new ObservableCollection<User>();
//... Populate the collection here.
}
}
then you will use this class as the DataContext of your UI:
//Window's constructor
public MainWindow()
{
InitializeComponent();
//Here we set the DataContext:
DataContext = new ViewModel();
}
Finally, you create the proper DataBindings in XAML:
<DataGrid ItemsSource="{Binding Users}"
x:Name="DataGrid"/>
<!-- ... -->
<TextBox Text="{Binding SelectedItem.Id, ElementName=DataGrid}"/>
Notice how I'm using an ElementName binding to bind the TextBox directly to the DataGrid.
This is the preferred, professional approach to WPF. I suggest that you read all the linked documentation and try to familiarize yourself more with this approach.

If you're populating your DataGrid with a List<SomeObject>, for example, try this:
var row = ((SomeObject)DataGrid1.Items[0]);
Just cast the item back to your class type, then access the properties on it. You may want to do a check to make sure there's something displayed in the grid before accessing Items[0].
You can sort different columns in your grid, and this will always grab the record displayed at the top.
Edit, after seeing the following comment:
When I click on first row in DATAGRID, this function should/must display user's ID in the textbox below data grid. That is all.
You can bind directly to your grid, to display the property you want from the currently selected row.
<DataGrid x:Name="DataGrid1" />
<TextBox Text="{Binding ElementName=DataGrid1, Path=SelectedItem.UserId}" />

Related

UWP: Live queries and searches with realm

I'm using Realm as my main database and sync engine and my question is that how do I do live queries for search?
for example when I use
var _age= 7;
Instance.All<Dog>().Where(d => d.Age == _age).AsRealmCollection();
and bind my listview to it, I need my view to be updated when I change the _age variable. As another word, I want to have a "Dynamic" query to my database. I want my view to be updated when I want to look for "Dogs" in different ages. But when I run this query again and assign new collection to ViewModel, my view does not update.
What shall I do?
UPDATE:
Here you can get a sample code so you can reproduce this issue:
https://github.com/Mohsens22/RelamTest
Also I must tell you that IRealmCollection<T> implements INotifyPropertyChanged by default so if you add any items to the collection with a "Write transaction" the view will be updated. More info can be found HERE
I have checked your code sample and I found Dogz will be recreate with Instance.All<Dog>().Where(z => z.Age == nxt).AsRealmCollection();. So you need two way bind model.
<ListView x:Name="itemListView" ItemsSource="{x:Bind Dogz,Mode=TwoWay}">
And this is document about bind that you could refer.

How to make List<Object> variable appear in DataBinding UI when using WPF in Visual Studio?

I'm in the process of learning WPF and currently exploring data binding. I have a DataGrid control on my form, and in my C# code for the form I have a List<string> variable.
I want to be able to use the Properties UI for the DataGrid in the designer to bind the List<string> to the DataGrid. I cannot figure out what I need to do or where I need to look in the UI to do this.
This is what I am doing:
Click my DataGrid in the UI designer to make it the active control.
Move to the Properties window.
Scroll down to the ItemsSource property.
Click on the field and the UI with Source, Path, Converter and Options pops up.
And when I get to this point I no longer know what to do.
I do not want to accomplish this by writing/modifying XAML. I want to know how it works using the UI.
Having never used the designer before, I can't be totally sure (your use case isn't quite clear either).
That being said, in my designer you
Set the "Binding Type" to "Data Context"
Select the "Custom" text box (needed for me because it doesn't see my DataContext)
Type the name of your property in the "Path" field (you can only bind to Properties)
Hit OK.
Note that this is the same as writing in XAML:
<DataGrid ItemsSource="{Binding MyItemCollection}"/>
<!-- or --!>
<DataGrid ItemsSource="{Binding Path=MytItemsCollection}"/>
There's a reason no one uses the designer....
The other options are more "advanced" binding concepts that you don't normally use on ItemsSource properties.
Note that DataGrid is a poor choice for displaying strings. ListView or ListBox are much better choices, as they don't assume your information has multiple pieces (like DataGrid does).
I understand not liking XAML, as it really intimidated me at first, but I will quickly say that it is a powerful tool. I am not sure how to do it through the designer, but in C# let's say you name your DataGrid 'myDataGrid' and your List is named 'stringList'. It is as simple as the following:
myDataGrid.ItemsSource = stringList;
and the data grid is now bound to your string list.
Thanks for asking the question! The properties window is so underrated.
First you must set the DataContext.
It's in the common section of the properties window. Set the data context to whatever view model you need. If you don't have a VM and the List is in the code behind, set the data context to relative source self.
Next in the Path write the name of your List.
Also, you may want to use ObservableCollection instead of List so your objects are updated in the UI as they change.

C# WPF radio buttons split onto different pages

I'm working on WPF (XAML) using the designer (very newbie) and C# as backing code.
I need to be able to have a few "pages" of Radio Buttons in the same group (i.e. clicking on item A on page 1 then clicking on B on page 2 should deselect A on page 1).
How would I go about doing this?
Thank you!
Note that the "buttons" are actually just radio buttons above images.
First, I would NOT recommend doing this. As a user, I would be very confused/surprised if my selections on one page affected a selection on a previous one.
As to how to accomplish it, I will assume you are using MVVM (as you should be in WPF). First, the ViewModel for each page needs to have a reference to the same backing property in the Model. In other words, your Model has a property like (where MyRadioSelection is some enum you are binding to):
public MyRadioSelection GlobalSelection {get; set;}
and your view models have:
public MyRadioSelection UserSelection
{
get {return Model.GlobalSelection;}
set
{
Model.GlobalSelection = value;
OnPropertyChanged(UserSelection);
}
}
Then you just need a ValueEquals converter (from this answer), bind all your radio buttons to the enum, and you should be good to go!
Please let me know if you would like a piece explained further. Also, posting your existing code would help improve this answer. Also note that your Model may need some way of notifying the ViewModels of external (another ViewModel's) changes to the backing property. You could approach this from several directions, but just implementing INotifyPropertyChanged and listening to it in the ViewModel would work.

Is there a quick way of adding an event to many controls at once in WPF?

I have 400+ textboxes on a page. The page is meant to be an exact replica of a paper form. The user is going to edit all of the fields and then save the data to the DB. The data is being pulled down into a DataTable from a SQL DB.
I'm planning on saving the data via the same DataTable or just via a bulk update. Not 100% on that. But, I need to get access to that data. And maybe I'm not doing this next best part the best and if I'm not, I'd appreciate it if I was informed of a better way.
When the DataTable gets the data, I assign each field into the appropriate control. Below is an example of how the data is being added.
foreach (DataRow CDR in ClaimDataTable.Rows){
if (CDR["BoxNumber"].ToString() == "1.1")
this.Box1_1.Text = CDR["DataValue"].ToString();
if (CDR["BoxNumber"].ToString() == "1.2")
this.Box1_2.Text = CDR["DataValue"].ToString();
if (CDR["BoxNumber"].ToString() == "1.3")
this.Box1_3.Text = CDR["DataValue"].ToString();
I wrote some code to automatically create that code. So I didn't manually write all 400+ lines.
What I was thinking, was that I could add a LostFocus event to each TextBox. Then when the control loses focus, I would create a class with a box name and the box value. Add that to a list and when they're ready to save, just loop through the list and do the bulk update with the BoxNumber and the box data.
Would that be feasible? Or is there a better method?
Thanks!
Look into event routing.
You should not create and access individual text-boxes but let the framework create them via datatemplating a collection, your above code is ze horror.
When the DataTable gets the data, I assign each field into the
appropriate control.
WPF is data binding and one does not generally load controls as you mentioned. Why is the code not binding to each control to a property which adheres to INotifyPropertyChanged?
Have the page's DataContext (DC) point to an instantiated class which adheres to InotifyPropertyChanged interface. The setting of the DC in that fashion will allow all controls on the page to use its datacontext by default.
In the class to be instantiated for the DC create a member property which calls PropertyChanged when the value is set using the INotifyPropertyChanged system.
Bind each TextBox Text property to that property on the class.
Then each control which needs that value will display it automatically after it has been set such as in this example.
<TextBlock Name="tbHeader"
Text="{Binding CDRData}" />
Then one only has to write the value to the property named CDRData once and all textboxes bound get the value.

Highlight certain rows in Listbox

I have a listbox I'm setting with a datasource of highscores
public class HighScore
{
public string Username {get;set;}
public int Score{get;set}
}
var IList<HighScore> HighScores = getAllTheScores();
MyListbox.ItemsSource = HighScores;
I want to change the background color of any rows which have a Username property equal to the currently logged in user (stored in AppSettings). I've seen Converters but this would need to somehow get hold of the currently logged in user which doesn't seem like something a converter should be responsible for getting.
I could also iterate the listbox items but from what I've seen that's not advised and I should be preferring binding to code behind drilling into controls.
Any suggestions as to how best achieve this much appreciated :)
Two suggestions. You already mentioned the first one, which is to use a ValueConverter. If value value is accessible from a viewmodel (recommended) than that is easy to pass along to the ValueConverter. If it is not stored in a view model then there are no worries with getting this from within the value converter provided it's named properly.
The second suggestion is to use a Behavior. The Behavior would be responsible for setting the background based on the user. I don't see much advantage here over a value converter except for the back that it's not a value converter. It would (almost) do the same thing. Overall I would recommend a value converter. Easy to implement, low code overhead and little xaml needed.

Categories

Resources