I'm using Linq to SQL classes in my WCF. Those classes are returned from the WCF methods to the Silverlight. Now, I want to add a custom property on a the generated class (Silverlight side) and trigger a PropertyChangedEvent on that particular property, based on another PropertyChangedEvent from another property. To be clear, here's a piece of code that doesn't work :
Partial Public Class DataConnection
Public Sub New()
AddHandler Me.PropertyChanged, AddressOf _PropertyChanged
End Sub
Private Sub _PropertyChanged(ByVal sender As Object, ByVal e As PropertyChangedEventArgs)
If e.PropertyName = "ConnectionType" Then
Me.RaisePropertyChanged("ConnectionTypeEnum")
End If
End Sub
Private _ConnectionTypeEnum As String
Public ReadOnly Property ConnectionTypeEnum() As String
Get
Select Case Me.ConnectionType
Return //Something based on ConnectionType //
End Select
End Get
End Property
End Class
The problem is that the code in New() is never executed, so I never know when the ConnectionType is changed, so I can't trigger the PropertyChanged on ConnectionTypeEnum. (this property is used a in One-Way binding so I need it)
Does anyone have a solution for this ?
Thanks
You can use OnDeserializedAttribute
<OnDeserializedAttribute()> _
Public Sub WhenDeserialized(context As StreamingContext)
AddHandler Me.PropertyChanged, AddressOf _PropertyChanged
End Sub
Related
I have my own class which uses INotifyPropertyChanged correctly (Raising updates events), but when a property of type DateTime updated and called (View.Run) the listView not updating untill another property changing (not this property)
Now with the code:
Public Class EntryInfo
Implements INotifyPropertyChanged
ReadOnly Property DateAccessed As Date
Get
.......
Return _Access
End Get
End Property
Readonly Property Property1 as object
Get
.......
Return _Property1
End Get
End Property
Friend Sub NotifyPropertyChanged(ByVal info As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
RaiseEvent ApropertyHasChanged()
End Sub
Then when I need to Change the "DateAccessProperty" I use this code:
Friend Sub SetAccessTime(Dt As Date)
_Access = Dt
NotifyPropertyChanged("DateAccessed")
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''
After this I have a ListView named "LV1"
Dim Coll as new observableCollection(Of EntryInfo)
....... filing "Coll" with items (EntryInfo)
Lv1.ItemsSource =Coll
Then I do the following:
Do some sort and group operations.
Changing "DateAccessed" value. so that the "ApropertyHasChanged" event fired and at this point I used the following code
Private Sub RefreshViewNow()
Dim _view As ListCollectionView = TryCast(CollectionViewSource.GetDefaultView(LV1.ItemsSource), ListCollectionView)
If _view IsNot Nothing Then _view.Refresh()
'\\\ Items.Refresh()
End Sub
But _view not refreshed.
But if the property "Property1" changed the _View refreshed.
Any help?
The solution is by set the following "_view" properties:
_view.IsLiveFiltering = True
_view.IsLiveGrouping = True
_view.IsLiveSorting = True
or at least one of them if you want one of them only to be activated.
I am using VB.NET and WPF within Visual Studio 2010 Express.
Currently, I have:
A DataGrid by the name of downloadListDG. This has a column which is a template containing an image.
An ObservableCollection of a custom DownloadListItem class.
This DownloadListItem has a public property which is another custom class.
This class has a private dim which is a StateType (a custom enum), and a public readonly property which returns a string depending on what the StateType is (actually an image URI if you're curious).
The DownloadListItem also has a public property which just returns the StateType (this is just for binding purposes)
My problem is that whenever the StateType changes, the image column in the DataGrid does not change. I have been trying to use the IPropertyChangedNofity, but nothing changes, so either I'm using it incorrectly or I need to use another method.
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
AddHandler ControllerRef.StateChanged, AddressOf StateChangeHandler
Private Sub StateChangeHandler(NewState As State)
MsgBox(NewState)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("CurrentState"))
End Sub
Thanks in advance
Make sure the PropertyChanged event is notifying the UI of the property name you are bound to, not the property that triggers the change. Example:
Imports System.ComponentModel
Public Class DownloadListItem : Implements INotifyPropertyChanged
Friend Enum StateEnum
State1 = 0
State2 = 1
End Enum
Private _CurrentState As StateEnum
Private Sub ChangeEnumValue(NewValue As StateEnum)
_CurrentState = NewValue
OnPropertyChanged("ImageURI")
End Sub
Public ReadOnly Property ImageURI As String
Get
' TODO: Implement conditional logic to return proper value based on CurrentState Enum
End Get
End Property
Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
Protected Sub OnPropertyChanged(PropertyName As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(PropertyName))
End Sub
End Class
i'm currently experimenting wpf communication between two views of different modules using prism IEventAggregator. publishing module and subscribing module is working fine, for some reason i can't understand why the subscriber UI is not updating.i place a button to display a msgbox at the subscriber module just to be sure that it receives it and it does. and i think i properly implement the INotifyPropertyChanged.
if i place subscribe in subscriber view's code-behind it works as i want it to be....do i do it the wrong way? please correct me. thanks.
a separate class for module message passing. this class is from this post http://www.shujaat.net/2010/12/wpf-eventaggregator-in-prism-40-cal.html
Public Class SendServices
Public Shared Property SendMessage As EventAggregator
Shared Sub New()
SendMessage = New EventAggregator
End Sub
End Class
Publisher :
Public Class Module1ViewModel
Private _msgsend As String
Public WriteOnly Property MessageSend As String
Set(value As String)
_msgsend = value
End Set
End Property
Public Sub Send()
SendServices.SendMessage.GetEvent(Of SendStringEvent).Publish(New SendString With {.Name = _msgsend})
End Sub
End Class
Subscriber :
Public Class Module2ViewModel
Implements INotifyPropertyChanged
Private _receivedMSG As String
Public Property ReceivedMSG As String
Get
Return _receivedMSG
End Get
Set(value As String)
_receivedMSG = value
OnPropertyChanged("ReceivedMSG")
End Set
End Property
'Binded to subscriber View button using interactions
Public Sub Received()
MsgBox(ReceivedMSG)
End Sub
Private Sub ReceivedMessage(msg As SendString)
_receivedMSG = msg.Name
End Sub
Public Sub New()
SendServices.SendMessage.GetEvent(Of SendStringEvent)().Subscribe(AddressOf ReceivedMessage, ThreadOption.UIThread, False)
End Sub
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Sub OnPropertyChanged(ByVal name As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
End Sub
End Class
Subscriber View code-behind
Public Class Module2View
Sub New()
InitializeComponent()
Me.DataContext = New Module2ViewModel
End Sub
End Class
and the binding part to display the message
<TextBox Height="23" HorizontalAlignment="Left" Margin="111,39,0,0" Name="TextBox1" VerticalAlignment="Top" Width="158" Text="{Binding Path=ReceviedMSG}"/>
You don't fire the OnPropertyChanged event because you are directly setting the field _receivedMSG in your handler which is bypassing the property setter which fires the event.
So you should use the property setter instead:
Private Sub ReceivedMessage(msg As SendString)
ReceivedMSG = msg.Name
End Sub
At the moment I have the following Command class:
Public Class SubscribeCommand
Implements ICommand
Private ReadOnly _vm As MainWindowViewModel
Public Sub New(ByVal vm As MainWindowViewModel)
_vm = vm
End Sub
Public Function CanExecute(ByVal parameter As Object) As Boolean Implements System.Windows.Input.ICommand.CanExecute
Return Not String.IsNullOrEmpty(_vm.Symbol)
End Function
Public Event CanExecuteChanged(ByVal sender As Object, ByVal e As System.EventArgs) Implements System.Windows.Input.ICommand.CanExecuteChanged
Public Sub Execute(ByVal parameter As Object) Implements System.Windows.Input.ICommand.Execute
_vm.Subscribe()
End Sub
End Class
In a tutorial i read, you have to implement add {} and remove {} for the canExecuteChanged-Event. But how can i do that, with vb.net?
thanks a lot..
I don't think you're required to implement the add and remove pieces for the CanExecuteChanged event. I'm pretty sure it'll work just fine the way you have it now. But if you did want to for some reason (to make it match what you see in this post in C#, for instance), you would change
Public Event CanExecuteChanged(ByVal sender As Object, ByVal e As System.EventArgs)
to
Public Custom Event CanExecuteChanged As EventHandler
AddHandler(ByVal value As EventHandler)
CommandManager.RequestSuggested += value
End AddHandler
RemoveHandler(ByVal value As EventHandler)
CommandManager.RequestSuggested -= value
End RemoveHandler
End Event
if you wanna use Commands in wpf please look at the wpf frameworks out there. you will find at least two nice command implementation:
RelayCommand
DelegateCommand
I have a class that implements INotifyPropertyChanged for a property.
I have a control that is bound to that property.
I have another class that listens to the propertychanged event. In the event handler of that class I change the value of the property in code.
The problem I have is that I don't want to do any logic in the event handler for the next time it will fire due to the change of the property due to code.
However if the user changes the value of the property in the mean time (via async gui input) I still want the logic to fire. I also need to make sure that the control gets updated (this is twoway binding).
What is the best way to do this without this becoming a complete mess?
One way to accomplish this would be to refactor the setter on your property so that it called a method taking a parameter indicating whether or not to raise the event. Here is a simple code sample:
Imports System.ComponentModel
Public Class Class1
Implements INotifyPropertyChanged
Public Property MyData() As String
Get
Return _myData
End Get
Set(ByVal value As String)
SetMyData(value, True)
End Set
End Property
Private Sub SetMyData(ByVal value As String, ByVal triggerPropertyChanged As Boolean)
_myData = value
If triggerPropertyChanged Then
OnPropertyChanged("MyData")
End If
End Sub
Private _myData As String
Private Sub OnPropertyChanged(ByVal propertyName As String)
SetMyData("new value", False)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
End Class
Your question is a bit vague, but you can check to see if the value has actually changed to determine if you should do your logic.
It would be better if you include some code to be more specific in your question.