Pass data between WPF windows - wpf

I have some code that works in winforms, but not in WPF apparently, the code is as follows:
This is set globally:
Private Property avar As Object
Public main As MainWindow
Public charchoice As Char
And then in the Window Loaded sub, this is placed:
charchoice = main.charchoice
Thing is, the next window doesn't pick up this variable, so how can I make it recognise and use it? Thanks Guys
Nick

I had a similar problem and discovered that you must create a public property in the MainWindow and pass a value to the property.
Please see this example from a similar question I posted.

Hey i got same problem when i am going to pass values between two forms.
I find its solution using a simple class and Shared property.
First I create a class named with cls_pass_val which is as under:-
Public Class cls_pass_val
Private Shared var_pass_val As String = ""
Public Shared Property Pass_val() As Char
Get
Return var_pass_val
End Get
Set(ByVal value As String)
var_pass_val = value
End Set
End Property
End Class
Now at the time of assigning a value:
cls_pass_val.Pass_val='A'
and at the time of retrieving the value:
Dim var_c as Char
var_c=cls_pass_val.Pass_val

Related

How to compare two objects by value

I need to compare two objects of the same class by value to see whether all their values match or not.
For background this is so I can compare before and after values of a wpf datagrid row
Say the objects are both House class with properties of name, street, town (all strings).
So the class would be
public class House
public property name as string
public property street as string
public property town as string
end class
Should I
1) override equals in the House class and in it check name=name, street=street, town=town
2) make the House class implement IComparable and create a compare function that implements it, checking each property as 1
3) there's a better way you know that I dont!
I'd appreciate an example based on this scenario if possible.
Many thanks
You should be using Option 1 : Overriding the Equals method.
Why ?
Because the Equals() method is supposed to be used when you want to compare if two objects are the same.
So what's the use of IComparabe ?
IComparable interface has a different purpose. Its goal is to check if an object is supposed to go before or after another object. Therefore this is used by sorting methods.
You can implement the IComparable interface and check if two object's CompareTo() method return 0. However it only means that they are supposed to get the same ranking, not that they are equals...
Is there another approach ?
There are plenty differents ways of doing what you want to do. But since there is a simple and elegant method that is here, let's use that one. The main difficulty in programming an application is to find the tools that are already here to do what you want...
So how to Override the Equals() method ?
This link to MSDN explains how to override the Equals method
In short (I'm just copy/pasting from MSDN and removing error checking for clarity here) :
Public Class Point
Protected x As Integer
Protected y As Integer
Public Sub New (xValue As Integer, yValue As Integer)
Me.x = xValue
Me.y = yValue
End Sub
Public Overrides Overloads Function Equals(obj As Object) As Boolean
Dim p As Point = CType(obj, Point)
Return Me.x = p.x And Me.y = p.y
End Function
End Class
Do not use this straight ahead and read article first, as you must do some error checking in the Equals, because it could throw some exception when converting Object to Point...

Dynamic Array as Class Property in VBScript

I am very new to VBScript, and not entirely sure if what I am doing is right.
I want to create a structure to hold onto a string and then an array of strings. The array of string will be dynamic, as I do not know how many entries are going to be in that list.
I have the following:
Class ExportMappings
Private _process_definition
Private _export_mappings : Set _export_mappings = CreateObject("System.Collection.ArrayList")
Public Property Let ProcessDefinition(procDef)
_process_definition= procDef
End Property
Public Property Get ProcessDefinition()
ProcessDefinition = _process_definition
End Property
Public Property Let ExportMappings(export)
_export_mappings = export
End Property
Public Sub AddMapping(map)
_export_mappings.Add map
End Sub
End Class
First, I am not sure if I declared the _export_mapping array properly.
Secondly, I do not know if I need a constructor to initialize my _export_mappings to an initial size. If so, I do not know how I would do that.
Lastly, my get and set methods for ExportMapping, I am not sure if that will work.
I would try to run it through a debugger, but the software I am using does not have the best debugger, and usually gives me a very vague description of what is wrong.
First things first:
VBScript variable names can't start with _; you can 'legalize' invalid names by putting them in [], but for starters I wouldn't do this
Code in Classes is allowed in methods only; your Private _export_mappings : Set _export_mappings = CreateObject("System.Collection.ArrayList") is invalid
After these changes, your code should compile. If you add code showing how you'd like to use this class, I'm willing to talk about second things (maybe tomorrow).

How to create a custom OpenFiledialog Property for a UserControl

When I right click a UserControl and select Properties, I want to create a custom property inside the UserControl properties that loads a file from an OpenFileDialog, like the ColumnDefinitions, but that browses inside my machine:
How can I achieve that? I've been searching but I'm a bit lost on where to start from.
NOTE: The image indicates that the property I want to create is one of the properties of the UserControl that appear when you Right click->Properties the UserControl.
Thanks!
I declared a property for searching execuble files in an OpenFileDialog in a WinForm project. The code is in VB .NET.
First create a Class like this:
Imports System.Drawing.Design
Imports System.Windows.Forms.Design
Imports System.Windows.Forms
Public Class ExecutableEditor : Inherits UITypeEditor
Public Overrides Function GetEditStyle(context As System.ComponentModel.ITypeDescriptorContext) As System.Drawing.Design.UITypeEditorEditStyle
Return UITypeEditorEditStyle.Modal
End Function
Public Overrides Function EditValue(context As System.ComponentModel.ITypeDescriptorContext, provider As System.IServiceProvider, value As Object) As Object
If context Is Nothing And context.Instance Is Nothing And provider Is Nothing Then
Return value
End If
Dim editor_service As IWindowsFormsEditorService = _
CType(provider.GetService(GetType(IWindowsFormsEditorService)), _
IWindowsFormsEditorService)
If editor_service Is Nothing Then Return value
Dim ofdEjecutable As New OpenFileDialog
ofdEjecutable.Title = "Select an executable file"
ofdEjecutable.FileName = Nothing
ofdEjecutable.Filter = "executable file|*.exe"
If ofdEjecutable.ShowDialog = DialogResult.OK Then
Return ofdEjecutable.FileName
Else
Return Nothing
End If
End Function
End Class
Then in the code of the UserControl declare a property like this:
Private _executable As String
<Category("Injection")> _
<EditorAttribute(GetType(ExecutableEditor), GetType(UITypeEditor))> _
Public Property Executable As String
Get
Return _executable
End Get
Set(value As String)
_executable = value
End Set
End Property
What I got from your question is that you want a Browsable Property for you user control. Going by this, for simple .net property add:
private string myString;
[Browsable(true)]
[Category("Other")]
public string MyProperty { get { return myString; } set { myString = value; } }
and in setter of the property load the file after validation.
If you want it to be dependancy property do the same but move the code of loading the file in the propertychange handler.

Silverlight Saving a Class Instance to Isolated Storage

Im just wondering how I go about saving an instance of a class to the silverlight isolated storage. I also need to know if it possible that the class that we save to isolated storage can have a list of instances of another class. Here is an example of the situation:
Public Class MySettingsToStore
private mPropertyA as string
Public Property PropertyA() As string
Get
Return mPropertyA
End Get
Set(ByVal value As string)
mPropertyA = value
End Set
End Property
private mlstOfSubClass as List(Of MySubClass)
Public Property lstOfSubClass() As List(Of MySubClass)
Get
Return mlstOfSubClass
End Get
Set(ByVal value As List(Of MySubClass))
mlstOfSubClass = value
End Set
End Property
End Class
Public Class MySubClass
private mPropertyA as string
Public Property PropertyA() As string
Get
Return mPropertyA
End Get
Set(ByVal value As string)
mPropertyA = value
End Set
End Property
private mPropertyB as string
Public Property PropertyB() As string
Get
Return mPropertyB
End Get
Set(ByVal value As string)
mPropertyB = value
End Set
End Property
End Class
So basically on load of the application I want to check if there is an instance of MySettingsToStore in the isolatedStorage if not I will create one and save it (and update it when needed), so the next time the application is started there will be an instance in the isolatedstorage to load.
Does anyone know how I go about this? Hope someone can help. Thanks in advance
One word: XMLSerializer
To elaborate a bit, you can serialize any class with public properties to a stream (e.g. in Isolated storage) and reverse that process on startup to load an existing file in ISO storage.
If a property is a collection of other classes, they too will be stored and restored by using XMLSerializer.

WPF Custom Control and exposing properties thru DependencyProperty

Ok - I'm pulling my hair out over what I thought was a simple scenario: create a custom Label for bilingual use that contained two additional properties (EnglishText, FrenchText). Currently its structured like this:
Public Class myCustomLabel
Inherits System.Windows.Controls.Label
Public myEnglishTextProperty As DependencyProperty = DependencyProperty.Register("myEnglishText", GetType(String), GetType(myCustomLabel), New PropertyMetadata("English", New PropertyChangedCallback(AddressOf TextChanged)))
Public myFrenchTextProperty As DependencyProperty = DependencyProperty.Register("myFrenchText", GetType(String), GetType(myCustomLabel), New PropertyMetadata("Francais", New PropertyChangedCallback(AddressOf TextChanged)))
Public Sub New()
'This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.
'This style is defined in themes\generic.xaml
DefaultStyleKeyProperty.OverrideMetadata(GetType(myCustomLabel), New FrameworkPropertyMetadata(GetType(myCustomLabel)))
End Sub
Public Property myEnglishText() As String
Get
Return MyBase.GetValue(myFrenchTextProperty)
End Get
Set(ByVal value As String)
MyBase.SetValue(myFrenchTextProperty, value)
End Set
End Property
Public Property myFrenchText() As String
Get
Return MyBase.GetValue(myFrenchTextProperty)
End Get
Set(ByVal value As String)
MyBase.SetValue(myFrenchTextProperty, value)
End Set
End Property
Private Sub TextChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
If DesignerProperties.GetIsInDesignMode(Me) = True Then
Me.Content = myEnglishText
Else
If myUser.Language = "E" Then
Me.Content = myEnglishText
Else
Me.Content = myFrenchText
End If
End If
End Sub
End Class
My test window grid xaml is simple:
<Grid>
<my:myCustomLabel myEnglishText="English Text" myFrenchText="English Text" Height="25" Width="100" Background="Aqua" Foreground="Black"/>
</Grid>
This seems to work in the development environment - changing the English and French texts change the in the design preview and it works when the app runs and the test window is opened. But only the first time - if I open the test window a second time I receive the following message:
'myEnglishText' property was already
registered by 'myCustomLabel'.
I understand now that if I change the dependency property declarations to shared then this problem goes away - but that leads to a host of other problems like the callback function being required to be shared as well - and thus unable to update the Content (which needs to be instantiated with the class). All I really want is the content property to be updated in design time when the english and french labels are changed.
Is there a way around this? Or maybe are dependency properties overkill for what I need?
You are registering your dependency properties as instance variables, and during the instance constructor. So they are getting registered again every time you instantiate the control, which causes an error the second time. As you have found out, dependency properties need to be static (Shared) members:
Public Shared myEnglishTextProperty As DependencyProperty =
DependencyProperty.Register("myEnglishText", GetType(String), GetType(myCustomLabel),
New PropertyMetadata("English", New PropertyChangedCallback(AddressOf TextChanged)))
You probably need to call OverrideMetadata in your shared constructor (type initialiser) rather than your instance constructor as well.
Regarding your issue with the callback needing to be shared: yes, it will be, but one of the arguments to the callback is the label instance. So you can just cast that to label and call an instance method on that:
private static void TextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((MyLabel)d).TextChanged();
}
private void TextChanged()
{
// your code here
}
(forgive C# syntax)
Is the reason you don't want the callback method to be shared because you're accessing the "me" instance? If that's all it is, make it shared and use the "d" parameter. I don't know VB well enough to show you the code, but just create a variable of type myCustomLabel and assign "d" to it (with a cast). Then use that variable (say "lbl") instead:
If DesignerProperties.GetIsInDesignMode(lbl) = True Then
lbl.Content = myEnglishText
Else
If myUser.Language = "E" Then
lbl.Content = myEnglishText
Else
lbl.Content = myFrenchText
End If
End If
Also, there's a slight bug in your example code. Try using this:
Public Property myEnglishText() As String
Get
Return MyBase.GetValue(myEnglishTextProperty)
End Get
Set(ByVal value As String)
MyBase.SetValue(myEnglishTextProperty, value)
End Set
End Property
Instead of this:
Public Property myEnglishText() As String
Get
Return MyBase.GetValue(myFrenchTextProperty)
End Get
Set(ByVal value As String)
MyBase.SetValue(myFrenchTextProperty, value)
End Set
End Property

Resources