Is there an attribute that ignores a method on design-time? - wpf

Something like:
<DesignTimeHidden()> _
Private Sub UserControl_IsVisibleChanged(sender As Object, _
e As DependencyPropertyChangedEventArgs) Handles Me.IsVisibleChanged
End Sub

It sounds like you want a method which, if called at design-time, is ignored, but can still be called at run-time.
This is not possible with an attribute. However your method code can check if it is being called at design time and return without doing anything. How you do this depends on your environment.
For components such as WinForms or
ASP.NET controls, check the
DesignMode property (note this is
not set until after construction, so
is not reliable in the constructor or
methods called from the constructor).
For WPF components, call
DesignerProperties.IsInDesignMode(this).

Related

Handling Events For Controls Added At Run Time

I am adding controls at run time in a WPF App, these are all different types of control so are passed as a UIElement. I then get the type of control and can set the properties using SetValue. As I have a lot of control types to implement what I am now trying to do is is add an event to each control but can only seem to do this using Addhandler which requires a lot of extra code for each control as shown below. I am looking for a solution to allow me to add the error handler to the UIElement without prior conversion using a Cast, I am not sure this is possible?
Select Case Control.GetType()
Case GetType(ExtendedTextBox)
Dim newControl As ExtendedTextBox = TryCast(Control, ExtendedTextBox)
'Dim newCtl As UIElement = TryCast(Control, ExtendedTextBox)
If newControl IsNot Nothing Then
newControl.SetValue(ExtendedTextBox.HorizontalAlignmentProperty, HorizontalAlignment.Left)
newControl.SetValue(ExtendedControlProperties.HighlightTextOnFocusProperty, True)
newControl.SetValue(ExtendedControlProperties.MandatoryProperty, True)
AddHandler newControl.HasErrors, AddressOf UpdateErrorStatus
End If
I was incorrectly prefixing my validation with "Customer." which as in inherited control was causing the issue, once removed it works as expected.

How do I resolve this apparent Catch22

I have a wpf custom control with (as is common) a shared constructor. This one looks like this;
Shared 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(VtlDataNavigator), New FrameworkPropertyMetadata(GetType(VtlDataNavigator)))
ItemsSourceProperty.OverrideMetadata(GetType(VtlDataNavigator), New FrameworkPropertyMetadata(Nothing, AddressOf OnItemsSourceHasChanged))
End Sub
The control inherits ItemsControl and I want to have notification of when the itemsSource changes hence the second line in the constructor. OnItemsSourceHasChanged needs to be a shared sub in order for the line in the constructor to compile. Fine.
In the shared sub I have the following:
Private Shared Function OnItemsSourceHasChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs) As Object
RecordCount = Items.SourceCollection.Cast(Of Object)().Count()
End Function
which of course fails to compile because you cannot refer to an instance method of a class from within a shared method without creating a specific instance of the class. Even If a create a separate non shared handler for this I will still end up with the same error when trying to call it.
In essence all I want is the total RecordCount from the ItemsSource (hence my need to know when it's changed) so that I can then assign that value to RecordCount. However what I appear to have instead is the proverbial catch 22 of errors.
The answer is probably staring me in the face, but for now it escapes me. Any Ideas?

WPF: call Command in MVVM after view is rendered?

I am designing a WPF app and using MVVM pattern. Let's say I have one view called View1, and it's DataContext is set to ViewModel1 in it's contractor. The VM has one Commandcalled RefreshCommand whose job is to calculate the data to be displayed on the view. Now I'd like to call this RefreshCommand right after my view is shown, but I don't know how to do that.
I tried to call it in the code-behind where I handle the Loadedevent for the usercontrol, something like this:
Private Sub AfterLoad(sender As Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
RefreshButton.Command.Execute(sender)
End Sub
However, that's when I noticed that at this moment the RefreshButton.Command is still set as Nothing. Note that in the UI interaction the invoke of this button/command is fine. So when should I call the command to perform such operation? Thanks!
That looks like it should work. Show your XAML and viewmodel?
Normally I would just have my VM get its data immediately and show the data in the View via bindings. Try executing the Refresh command in your VM constructor

WPF and VB.net: Data Binding to Separate Class created outside of Expression Blend

I have a WPF application with form that has a textbox named "txtStatusWindow". I also have a vb.net class handed to me by a co-worker that needs to be called and executed by the code in my application code-behind. My co-worker insists that I will need to use common .net events to update the textbox on my form.
The separate vb.net class:
Public Class globalclass
Public Event txtStatusWindow(ByVal Text As String)
Public Sub InitializeProgram()
RaiseEvent txtStatusWindow("Updating something.")
System.Threading.Thread.Sleep(2000)
RaiseEvent txtStatusWindow("Updating something else.")
System.Threading.Thread.Sleep(2000)
RaiseEvent txtStatusWindow("Updating something other than else.")
System.Threading.Thread.Sleep(2000)
RaiseEvent txtStatusWindow("Updating something other than the else stuff.")
System.Threading.Thread.Sleep(2000)
End Sub
End Class
I need to be able to call the sub "InitializeProgram()" from my code-behind, and it needs to be able to update "txtStatusWindow.text" as it runs.
I told him that the updating of the text box can be done with data-binding, but I don't know how to integrate a separate class like this into my project, how to call methods in it, or how to cause it to update my text blocks through data binding.
I also suggested that the methods in this class aren't optimal for connecting to the WPF project anyway, but he just wrote it as an example to discover how to connect the two projects.
Eventually, I will need to integrate classes like these that will be running separate threads to update their data from a dynamic source, and cause many controls to update in my application.
So far, the only way we have been able to get this to work from my code-behind is this:
Partial Public Class SplashScreen
Dim NewText as String
Public WithEvents Globals As globalclass = New globalclass
Public Delegate Sub StringDelegate(ByVal Text As String)
Public SplashText As String
Public Sub New()
MyBase.New()
Me.InitializeComponent()
Me.Show()
Globals.InitializeProgram()
End Sub
Public Sub UpdateSplashscreenHandler(ByVal Text As String) Handles Globals.UpdateSplashScreen
StatusWindowText.Text = Text
End Sub
Notwithstanding the fact that the WPF screen "freezes" until the "globalclass InitializeProgram" method completes (txtStatusWindow.Text does not update while sub without using the esoteric "refresh" extension...), I fully believe we are going about this the wrong way.
There are precious few examples out there concerning the integration and then binding to objects in existing code. Thanks for examining our little quandary.
If this status window is in XAML and the status window is a UserControl, then add a StatusText dependency property to the status window. Then, in the XAML you can bind to the value of that property with something like:
<UserControl x:Name="MyStatusWindow" ...>
<TextBlock Text="{Binding Path=StatusText, ElementName=MyStatusWindow}" />
</UserControl>
Then, from your event, just update the value of that StatusText property.
(Is that even close to what you were asking?)
Also, about that freezing: Instead of doing that updating in the constructor of that class, you might want to do it from the Loaded event of that control. It will still be freezing, though, unless you move it to a separate thread. Right now, that's happening on the same thread that the UI message pump is running on. This is the Dispatcher for that UI.

Programatically setting design-time properties in Windows.Forms control

Is there an easy way to programatically setting a property value on a control such that it will be persisted in the designer-generated code?
I imagine a piece of code in the control constructor or load event which is executed when i open the control in design mode, but sets a property such that it will be persisted the same way as if I changed the value manually through the properties grid.
Edit: Yes, this would be the same as editing the designer code manually, but I want to do it programatically.
Presuming I understand the question
You can databind that property to a setting, using the Visual studio Gui. Check the properties for that control, under the Data section for (Application Settings), (Property Bindings).
It depends on what kind of functionality you want. If you only need the properties to be set when you add the control to a form, then setting the properties in the control's constructor works perfectly. However, changes you make using the Properties panel will take precedence, and setting properties in the control's constructor won't necessarily affect existing instances of the control.
If you want to be able to change the properties for instances of the control in one place, assigning bindings in (application settings), (property bindings) works. Then you can modify all the bindings from the Settings.settings file. This still requires you to assign property bindings for each instance of the control, though.
Now for the finale. If you want to set properties in the control's class that affect all instances of the control, whether the instances are yet to be created or already exist, you have to get a little creative. I found a solution, but it may not be the best. My solution goes like this:
In the control's constructor, for each property you want to set, you:
Store the desired value in a private variable.
Assign the variable's value to the property.
Assign an event handler that assigns the variable's value to the property whenever the property is changed.
A downside is the amount of coding for each property. Also, you wouldn't be able to change the properties from the Properties pane.
Do you think about something like:
if (this.DesignMode)
{
// do somthing
}
If you put this into the constructor remember to call InitializeComponent() before.
What about:
Private Function GetPropertyByName(ByVal propName As String) _
As PropertyDescriptor
Dim prop As PropertyDescriptor
prop = TypeDescriptor.GetProperties(l_dWindow)(propName)
If prop Is Nothing Then
Throw New ArgumentException( _
"Matching ColorLabel property not found!", propName)
Else
Return prop
End If
End Function
Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
GetPropertyByName("AnyPublicProperty").SetValue(AnyControl, "AnyStringVALUE")
Me.DialogResult = DialogResult.OK
End Sub

Resources