Looping through objects to get their properties in Windows Phone - c#

I'm trying to develop a game in Windows Phone. I'm a beginner using c# and xaml. In the xaml I've objects with the same properties only Tag property is different. What I want to do is to loop througth object tags and change for another object (image) if I find a specific tag.
I've tried some code, like this:
foreach(Image tag in img) //but it says:
foreach statement cannot operate on variables of type 'Windows.Ui.Xaml.Controls.Image' because 'Windows.Ui.Xaml.Controls.Image' does not contain a public definition for 'GetEnumerator'...

Since as a beginner you won't likely use MVVM and just leave everything in the View, what you can do is just cycle through the LayoutRoot. If you have other Panel in the layoutroot that contain images, you want to do it recursively:
MainPage()
{
DoSomethingToImages(LayoutRoot);
}
DoSomethingToImages(Panel panel)
{
foreach(Image img in panel.Children.Where(x=> x is Image))
{
DoSomething(img);
}
var panels = panel.Children.Where(x=> x is Panel);
if (panels.Count > 0)
{
foreach(Panel p in panels)
{
DoSomethingToImages(p);
}
}
}
On the other hand, this is obviously bad practice, and you would normally bind your images to your viewmodel. The only exception might be heavily customised user controls to make things work that'd be otherwise extremely time-consuming to work around with MVVM. (Note: I think that MVVM is not always necessary for custom controls, since many times all you want is some custom graphical behaviour, like a button that takes an Image Background for it's pressed state as well, and that stuff belongs to the view, but you can usually solve that with a dependency property in the view and some XAML tweaking. Also, separating the ViewModel for a custom control makes it a bit harder to copy it to another project if you put it inside your own project - you have to find the viewmodel as well! :) ).

Like others have said, you'll need a collection to loop through.
Personally, I like dictionaries.
Here's an example I think you might be able to modify for your own purposes.
This will enable you to "loop though object tags", however as HighCore mentioned, it's probably not "the right way" to do whatever you're ultimately trying to accomplish.
Image img1 = new Image();
Image img2 = new Image();
Image img3 = new Image();
img1.Tag = "tag1";
img2.Tag = "tag2";
img3.Tag = "tag3";
Dictionary<string, Image> ImgDictionary = new Dictionary<string, Image>();
ImgDictionary.Add(img1.Tag.ToString(), img1);
ImgDictionary.Add(img2.Tag.ToString(), img2);
ImgDictionary.Add(img3.Tag.ToString(), img3);
foreach (KeyValuePair<string, Image> i in ImgDictionary)
{
// do stuff with i.Value or i.Key
}
string tmp_TagName = "tag1";
if (ImgDictionary.ContainsKey(tmp_TagName))
{
Image ReturnImage;
ImgDictionary.TryGetValue(tmp_TagName, out ReturnImage);
// do something with your ReturnImage...
}

Related

Change UniformGrid child item during runtime

I'm currently trying to populate a UniformGrid in WPF.
Some context: I'm trying to build a 2D Sidescroller (I know, WPF is not the best solution to that and I should use Unity or something else. I'd like to try it though). Now, for the map I was thinking about using a UniformGrid and using the children as tiles for my map.
So far, I'm adding empty children to the UniformGrid using this piece of code:
private void CreateMapTiles() {
for (int i = 0; i < 30; i++) {
for (int j = 0; j < 45; j++) {
this.MapGrid.Children.Add(new Image());
}
}
}
Where MapGrid is my UniformGrid.
So, in the end, I want to have 30x45 children.
Now I want to dynamically edit those children in CodeBehind, i.e. make those children an image. Or put another way, I want to update, let's say, the child at index 5 to display another image from my resources, than it did before.
I was thinking about using something like this:
this.MapGrid.Children[1] = new Image() { Source = ReturnSomeSource() };
But for obvious reasons, this doesn't work.
Is there any way i can assign a value to the children during runtime?
I've also played around with this.MapGrid.Children[1].SetCurrentValue() a bit, but neither did I really understand what I was doing, nor did it work in any way.
Does the possibility even exist, to change the UniformGrid children during runtime?
Would a normal Grid do a better job? I wanted to avoid that, because the UniformGrid children are arranged and sized automatically the way i need them without any more effort.
Rather than replacing Imagewith a new Image, change the source on the already existing image.
var tileImage = this.MapGrid.Children[1] as Image;
tileImage.Source = ReturnSomeSource();

MVVM architecture WPF

I have a little architecture problem with MVVM in WPF. I am having View which contains option to write some code or scan QRCode with computers camera.
If user choose to not scan the code, I can bindCommand` and there is no problem.
Problem is there when user choose to scan qrcode.
When user press scan code part of screen is being collapsed and camera shows on the screen. I have to do it in View code behind, so the code I am getting in View which is not good in MVVM.
Here how View`s code look like:
private void Scan_Click(object sender, RoutedEventArgs e)
{
if (_finalVideo.IsRunning)
{
_finalVideo.Stop();
}
_finalVideo = new VideoCaptureDevice(_cameraDevices[CamerasList.SelectedIndex].MonikerString);
_finalVideo.NewFrame += (s, a) =>
{
try
{
System.Drawing.Image img = (Bitmap)a.Frame.Clone();
var ms = new MemoryStream();
img.Save(ms, ImageFormat.Bmp);
ms.Seek(0, SeekOrigin.Begin);
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = ms;
bitmapImage.EndInit();
bitmapImage.Freeze();
Dispatcher.BeginInvoke(new ThreadStart(() =>
{
CameraStream.Source = bitmapImage;
ReadQrCode(bitmapImage);
}));
}
catch
{
//exc
}
};
_finalVideo.Start();
}
How I can solve that problem with MVVM?
That's quite simple, once you get the grip of it and know the difference between a "user control" and a view.
The first statement is, that ideally the code behind should be empty for a view. This is true.
However, this do not apply for user controls. User controls can and should have code behind, because they need to work self-sustained and do not have their logic extracted into some view model class.
So what's the difference between a user control and a view? Yes, they both generally derive on UserControl, but this do not make a view a user control by default. What matters is that, a view is very specific piece of UI made for one application which is very unlikely to be reused in other application.
For example, a CustomerDetailView or CustomerDetailPage in Application A is going to be different than the same view for Application B, because Application B will likely have different requirements for a CustomerDetailView.
A user control on the other side is meant to be reusable across applications, for example DatePicker, CalendarControl or a CameraControl. This control can be used in multiple applications that may need a camera for example.
Important thing here is, that the "user control" has no knowledge of your application structure, so no viewmodels, no business/domain models etc. If you want to allow ViewModels to bind to your user control (ICommand for starting and call backs for example, or bind the resulting picture to the ViewModel), then you put dependency properties into your user control.
When you use this user control in your application, you just bind your view model to these dependency properties (DP) and you got your abstraction.
TL;DR:
Code behind in a view is bad, code behind in a user control is necessary.

Draw bitmaps on window and update them 'x' times per second

Im new in Wpf C# programming and have maybe a stupid question.
I have a form and I need to create some controls with dynamic names.
(For Ex.: Grid: 'main' Controls: "str"+(int)i)
And I need to set Property Margin of this Controls OnTick.
So, Ik how to add this Controls, but have some problems in changing their properties.
Some code:
Image img = new Image();
img.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/img.png"));
img.Name = "str_" + i;
img.Margin = new Thickness(-10,-10,0,0);
img.Width = 1;
img.Height = 2;
main.Children.Add(img);
// ToDo Something like this:
main["str_"+i].Margin = new Thickness(x,y,0,0);
So, the question is: How to Edit property of already Created Dynamic control?
Update.
I found it rather stupid to create tons of controls except of refreshing drawings.
Now I have no idea what is the best way of drawing bitmaps on form.
For example:
I have List of locations of bitmaps.
I need to update the
bitmap's locations 'x' times per second.
Look at the next solution. Here is the code that references to the properties of an existing controls by it's (control's) name. It changes the control's set of properties according to the set of properties you support in view model (or code behind). If you will be interested I can make the adaptation to achieve your set of requirements. Here is the link
WPF user control, access dependency properties of component elements .
regards,

How to create a list of panels already existing in WinForm Application (C#)

Context:
I am creating mock-ups for a web based application. I use WinForms Application to do this. In the future I will use WebForms but this question applies to both I'm sure.
Question:
I have panels that are transparent which I place over a webpage-sized picturebox. The panels act as clickable "links" to "navigate" to "pages".
In actuality when a panel is clicked the picturebox (which serves as the background) changes to a screen capture of a different webpage giving the appearance of web navigation. The panels act as masks on things users click on to navigate.
I would like to add these existing panels into a list for the purpose of changing them.
For example, I would like to change their .Enabled attribute set to false; in one statement.
I currently accomplish this by doing this:
public void TurnOffPanels()
{
aPnl.Enabled = false;
bPnl.Enabled = false;
cPnl.Enabled = false;
dPnl.Enabled = false;
ePnl.Enabled = false;
fPnl.Enabled = false;
{
My question is: how can code this using a list of my panels?
PS: This is my first question here so please feel free to berate me for format, noobness...whateves
Oof, well, I wouldn't use winforms applications for mockups. There's plenty of cheap mockup applications like balsamiq and the like to do that, or gimp if you want to provide a visual aid.
However, I think you're meaning to say that you're developing "prototypes" in winforms. Prototypes allow people to interact while mockups are just flat images.
Anyway, if you want to hide a list of panels, you can just create a field in your codebehind of the panels you want to flicker, and just operate on that.
iE:
public class Form {
List<Panel> myPanels = new List<Panel>();
public Form() {
myPanels.Add(aPnl);
myPanels.Add(bPnl);
//etc
}
public TurnOffPanels(){
foreach(var panel in myPanels){
panel.Enabled = false;
}
}
}
Edit: Also your question is formatted fine, and you gave plenty of detail. As far as first questions go, good job!
If the panel are Childrens of the same form, then:
foreach(Panel p in this.Controls)
p.Enabled = false;

Trying to figure out how user control works

I have made a control library and two user controls.
userControl_1 contains a Panel and an ImageList that I have "loaded" with
images in design time.
userControl_2 contains a PictureBox
I have placed userControl_1 on a windows form. The userControl_2 is placed on the panel area in userControl_1.
The goal is to choose a image from the imageList and display it with the pictureBox, something like this:
nameOfPictureBox.Image = nameOfList.Image[number]
But I don't get it to work. I don't understand how to communicate between the user controls? I guess the piece of code above should be inside the userControl_1? But where do I put the code, inside the userControl_1.cs class file or the userControl_1.Designer.cs file?
Preciate some help! Thanks!
The designer file is generally only used for web control definitions, and is generated, so should not be the place for your code.
You will want to extend any functionality into the code behind file (.cs) of the user control.
One easy way to expose data from a user control is to create public properties in the code behind of the user control to encapsulate the knowledge of the control but still expose data.
Something like this on the UserControl_2 class:
public Image PictureBoxImage{
get { return pictureBox.Image; }
set { pictureBox.Image = value; }
}
You then have an easy property to work with that can hide the inner structure of the control, but still allow your UserControl_1 code behind to set it.
KDiTraglia's code can then be tweaked to do something like:
foreach(var item in this.Panel)
{
if (item is UserControl_2)
{
var ctrl = (UserControl_2)item;
ctrl.PictureBoxImage = ...
}
}
This then allows the user control to delegate down to the appropriate inner controls, without UserControl_1 needing to know about that structure.

Categories

Resources