Inserting XAML elements through C# - c#

I'm just starting with Universal Windows Platform and actually C# as well (I've got a C background) and just trying to get my feet wet with a basic accounting app meant to keep track of a checkbook. The way it works is simple, the user either presses + or - buttons and specifies the name of the transaction and the amount either credited or debited, hits ok and that transaction is inserted as a row.
So it would look something like this
Gas ($20) 1/5/17 _delete_button_
Paycheck $2400 1/3/17 _delete_button_
Total $2380
....
So each row has 2 editable text boxes (name and amount), one textfield for date, and one button to delete that row.
Now my first instinct as a C programmer is just to create a struct with those variables and every time user inserts a row just populate the struct and push it on a stack. However I just want to make sure that this is the best way to do this and I'm not missing some feature of XAML that would let me do this.

"Now my first instinct as a C programmer is just to create a struct
with those variables and every time user inserts a row just populate
the struct and push it on a stack. However I just want to make sure
that this is the best way to do this and I'm not missing some feature
of XAML that would let me do this."
This question is dangerously close to not meeting the requirements for a good question because it is too broad, but I will answer anyway due to remembering the pain I went through with XAML when new. Whether new or experienced (and I am at most in the "intermediate" category), it seems XAML has its bits that will always send you looking for help. But I digress.
The standard is to create your model, then somehow connect (or "bind") the appropriate parts of the model to your view.
You would use C# (actually can use VB or F# or others also) for your model. This is where you would create your "struct" you are referring to. This would define your individual transaction. Then, create a collection of these transactions, again in your model.
In XAML, you bind to this collection. You have a control (a visual element in your view) that displays all transactions. You have a control for specifying the name of a specific transaction, for selecting a transaction, for inserting, for deleting, etc. All of these controls interact with the model through the bindings.
So, to answer your question, yes you are missing a feature of XAML. It is called binding. Not to be sarcastic but unfortunately, binding is a technology worthy of months of study. Sorry, but you will want to go back to C with no UI at first. Keep at it! If you want to do the universal app thing, it is worth it. You may even find yourself liking (parts of) it.
Link to get thou started:
WPF and other XAML-related

Related

UserControl content not updating

I'm creating a simple UWP application for myself and stuck with lack of understanding of how binding and all that stuff works. Don't know how to explain it better So I created a simple example: https://gist.github.com/anonymous/744dc688d0663a3c14b7a2fc424316f8
The program has a list of selectable items on main screen. I can select several items, press a button and program will show new floating panel, with selected items (And I do further management of these items in my original program). I want this panel to be separate control because my MainPage is already overfilled with code.
The problem is. When I click on the button first time - it works as I expect. But then, when I change selected items and click button again, it shows panel with items from first selection.
My question is - how to do make it work? I have a feeling that it has to be something with INotifyPropertyChanged but cannot understand it.
And I also would be glad to hear the overall recommendations. I'm not c# developer. I'm actually sys. admin but I know a little of python and I learned Delphi 7 in university. So I'm kind of learning c# in process of creation of this application.
UPD: If I change line 28 of SelectedItemsView.xaml from
ItemsSource="{x:Bind SelectedItems}"
To
ItemsSource="{Binding SelectedItems, ElementName=SelectedItemsViewRoot}"
(and add x:Name="SelectedItemsViewRoot" to user control attributes). It works as needed. So new question arrives - is this correct way to do this? I though that Binding is kind of legacy and x:Bind is newer approach that should be used in new apps.
It's ok to use {Binding}, but if you want to stick with {x:Bind}, you can do this with OneWay mode (instead of default OneTime). For example: {x:Bind SelectedItems, Mode=OneWay}.
I strongly encourage you to read these two official tutorials:
Data binding overview and Data binding in depth.
In short, {Binding} is not legacy. It's actually a bit more flexible, but it's performed in runtime, while {x:Bind} is perfmormed at compile time, thus a bit more performant.

massive string array (40000) elements in listbox

I know this is a stupid question, I need to let you guys know that I am fully aware that it is useless in 99% of situations to make a listbox with this many elements in c#:
That being said I need this to be done...is there any way to populate a listbox with 40000 elements without it completely destroying performance/freezing up, thanks!
note: I have tried it, this is per the exact requirements of a professor...when adding 40000 elements through a DataSource and DataBind the application freezes up
You tell me.
for(i=0;i<40000;i++)
{
listBox1.Items.Add("click me");
}
Even if is possible (I never tried it), the usability for this form will be 0.
In that cases a more usable implementation is via lookup text-boxes and lists, where the user can enter a text to search record that matches this text and displays them in a any kind of list.
It is of course possible to do it, but not very practicable.
When using a desktop technology like WinForms or WPF, for a large number of items like this you are better off using something like an auto complete textbox, and have it set to filter/search after the user has typed two or three characters. In this case you can also use a control that offers scrolling virtualisation - this means that there is only a limited number of UI elements created in the scrolling portion of the dropdown, and those elements get reused when a scroll occurs. If you don't use virtualisation then a new element gets created for every list item that gets scrolled in to view. (Note that Silverlight controls have this functionality - just in case it's an option).
For ASP.NET though I would suggest that you do not want to do anything that would cause a large transfer of data (large items, or small items but lots of them) as it won't be performant. Instead you should look to do what Google does - retrieve search results in a paged fashion.

How do I pass values from a database between pages in WPF?

I created an application that connects to an SDF database. The user is given a list of movies in a cinema. The user can select a movie and press an 'ok' button.
The user should then be presented with another datagrid which contains all the information of that movie.
I've tried passing the SelectedIndex between the two pages, it sends the SelectedIndex to the information page, but it won't assign it to the same SelectedIndex.
public Desc(int input_id)
{
InitializeComponent();
cinemaEntities = new cinema1.cinemaDBEntities();
movieViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("moviesViewSource")));
System.Data.Objects.ObjectQuery<cinema1.movie> moviesQuery = this.GetMovieQuery(cinemaEntities);
movieViewSource.Source = moviesQuery.Execute(System.Data.Objects.MergeOption.OverwriteChanges);
moviesListView.SelectedIndex = id;
What to do depends on the purpose of the software, but in any case I would recommend to spend a little more effort on the architecture of your software. As you want to use WPF, you should decide whether to go for a MVVM (Model-View-ViewModel) approach which is highly maintainable and has numerous advantages, but demands some time to get familiar with. The quick solution which is absoulutely fine for small or simple apllications is to code your GUI logic in the codebehind of your views and controls.
Anyway, I would create a model layer which mirrors your database data in according types (MovieDatabase has a Collection of Movies, etc. etc.). Then write an adapter to fill the model from the database.Then either use the model in your views - if you want to do it quickly - or write ViewModels to your Models (which is better) and use those in your views.
This being said, from the code you posted its hard to tell, what the problem is. Do you have a little bit more context? Why don't you pass the SelectedItem?
Why not just pass the Movie object to the second page? And then use .SelectedItem. Why does the second page need the whole list anyway if it is detail for just one movie?

How to approach data-binding a BindingList of Lists to a DataGridView in C#?

I'm writing a program that functions as an Excel-style dictionary. Basically, it allows the user to add rows, edit rows, search through them, and so on. I use it for storing and studying vocabulary for foreign languages.
I've gotten a version up and running that I'm quite happy with. It uses a BindingList as a data source for a DataGridView in order to track changes and record them back to the BindingList that I use to store all the vocabulary, and the list itself is made up of a custom class I named "Term", that has properties for "English Word", "Spanish Word", "Examples", ect. What it doesn't do is let the user customize the fields, and that's where my problem comes in. It's pretty much "hard-coded" in that even if I'm studying Spanish or French, the Term class is going to be using the property for "Kanji" from Japanese.
I want to be able to have the user type in what fields they want the dictionary to display and keep track of--basically, they should be able to rename and add/remove columns from the DataGridView. My first thought was to implement this as a List, which stores the names of the fields (and accordingly the number of them, by using the List's length). Then, I would have a Word class that has a List property, and each string in the list represents one of the fields. Then I create a BindingList of this Word class, which leaves me with a BindingList of Lists.
When I try to databind my List list to my DataGridView, the grid comes up empty--it apparently has no idea how I want the data to be displayed and I'm having great difficulty figuring out how to tell it to. I'm not even sure if my approach of having a List of Lists is a good way to implement customizable fields, but it's the best I could think of. In any event, can anyone recommend a way to approach this that lets me add the fields to the table, but also tracks changes and pastes them back to the original source? I need the grid to be used as an editing tool for the user to not only add new elements, but also change existing ones.
It's a personal project, but it's driving me a bit crazy. I was up until 5AM last night trying to figure it out and came up empty-handed. Thanks very much for reading!
I've read your post a couple of times. I'm not sure I understand completly. If I don't, please give some details and I'll try to help.
If I had to do a Excel-like DataGridView, I think I'd use an Array. I would create an array of, say, 256 by 256 and put it as DataSource. Then after the user edits, you read the whole DataGrid and rewrite if it differs from the array you originally had.
I think you might be interested in this class:
http://www.codeproject.com/KB/grid/DGVColumnSelector.aspx
It allows the user to dynamically display which columns are shown in the DataGridView

Two-way data binding objects

I used an application recently that was awe-inspiring. All the forms inherited from their own classes and a 'form' came with an amazing amount of functionality and looked the nuts.
What I'm interested in is this 'feature' of the form. This was a C# WinForms project and blew me away.
The forms were bound to objects that the group had written to support two-way data binding (to an extent). The way they behaved was pretty simple:
The data input forms all had controls that inherited from textbox and these were bound to properties of an object, Entering data immediately validated it and the box was a light pink if validation failed and a light green if it passed. If the box ever turns blue this actually means the value in the database the form is bound to has changed and your changes to the controls were immediately saved when valid values entered. It was the case that sometimes a section of controls had to be filled before a save occured. But it was all automatic. You could stop at any point and come back later and continue without actually saving yourself.
And like I say if someone else is editing the same record values they change caused your textboxes to become blue and you knew you needed to reload the screen to see up to date information.
All of this came from using their own form class they had written and their own textbox controls bound to an objects property.
I'm mainly wondering how the hell did the object figure out the value had been changed by someone else. It surely isn't polling the database. This system was amazing. The brilliance didn't stop there.
For simplicity. How might I create an object or collection of objects to mimic the bahaviour. I'm not going to but I can't even see how.
Thanks
I'm pretty sure that anything involving other people's changes would have needed to hit the database. For two-way binding, all you really need is change notification - i.e. INotifyPropertyChanged (or a FooChanged event for every Foo property). This is all abstracted into TypeDescriptor - i.e. any binding that uses the regular PropertyDescriptor implementation (which it should) will know about notifications via SupportsChangeEvents, AddValueChanged and RemoveValueChanged.
For validation - IDataErrorInfo is your friend; by implementing this, you can volunteer validation information (which is used and displayed by several controls, such as DataGridView). i.e.
IDataErrorInfo dei = obj as IDataErrorInfo;
if(dei != null) { // supports validation
string err = dei["PropName"]; // or .Error for overall status
bool clean = string.IsNullOrEmpty(err);
}
Note that an alternative approach would be to have a Color property on the data aobject, and bind that directly to the textbox etc.

Categories