英文:
How do I bind to an object in my model to a user control in WPF?
问题
I'm trying to populate labels in a user control. The code-behind my user control creates an object, and I'm trying to bind the label contents to properties in that object. The class creating the object implements INotifyPropertyChanges, and has several public properties. I created binding within the XAML, and Visual Studio has picked this up, with intellisense offering me the properties to bind to. However, when I run, the labels are all blank.
If I create a property directly in my code behind which just calls from the object (and appropriately change my datacontext), it works.
I'm not too experienced with WPF - I must have missed something but I just don't know what?!
When my XAML looks like this, neither label is populated. If I adjust the data context to the control rather than the instrument object, The ConStatus label appropriately populates (but does not update as the user control doesn't implement INotifyPropertyChange):
<WrapPanel Grid.Row="1" DataContext="{Binding instrument}">
<Label Name="PortName" Width="100" Content="{Binding ConnectionString}" HorizontalAlignment="Right"/>
<Label Name="ConStatus" Width="200" Content="{Binding UniName}" HorizontalAlignment="Left"/>
</WrapPanel>
My code-behind looks like this:
Public Class UnifaceControl
Inherits UserControl
Public instrument As UnifaceModel
Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
FindUniface("uniface")
End Sub
Public Sub FindUniface(Portname As String)
instrument = New UnifaceModel(Portname)
instrument.Connect()
End Sub
ReadOnly Property UniName
Get
Return instrument.Connected
End Get
End Property
End Class
And here's a sample of the UnifaceModel object:
Public Class UnifaceModel
Implements INotifyPropertyChanged
Shared Log As NLog.Logger = NLog.LogManager.GetCurrentClassLogger()
Dim _ConnectionString As String
Public Property ConnectionString As String
Get
Return _ConnectionString
End Get
Set(value As String)
_ConnectionString = value
OnPropertyChanged()
End Set
End Property
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Sub OnPropertyChanged(<CallerMemberName> Optional propertyName As String = Nothing)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
英文:
I'm trying to populate labels in a user control. The code-behind my user control creates an object, and I'm trying to bind the label contents to properties in that object. The class creating the object implements INotifyPropertyChanges, and has several public properties. I created binding within the XAML, and Visual Studio has picked this up, with intellisense offering me the properties to bind to. However, when I run, the labels are all blank.
If I create a property directly in my code behind which just calls from the object (and appropriately change my datacontext), it works.
I'm not too experienced with WPF - I must have missed something but I just don't know what?!
When my XAML looks like this, neither label is populated. If I adjust the data context to the control rather than the instrument object, The ConStatus label appropriately populates (but does not update as the user control doesn't implement INotifyPropertyChange:
<WrapPanel Grid.Row="1" DataContext="{Binding instrument}">
<Label Name="PortName" Width="100" Content="{Binding ConnectionString}" HorizontalAlignment="Right"/>
<Label Name="ConStatus" Width="200" Content="{Binding UniName}" HorizontalAlignment="Left"/>
</WrapPanel>
My code-behind looks like this:
Public Class UnifaceControl
Inherits UserControl
Public instrument As UnifaceModel
Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
FindUniface("uniface")
End Sub
Public Sub FindUniface(Portname As String)
instrument = New UnifaceModel(Portname)
instrument.Connect()
End Sub
ReadOnly Property UniName
Get
Return instrument.Connected
End Get
End Property
End Class
And here's a sample of the UnifaceModel object:
Public Class UnifaceModel
Implements INotifyPropertyChanged
Shared Log As NLog.Logger = NLog.LogManager.GetCurrentClassLogger()
Dim _ConnectionString As String
Public Property ConnectionString As String
Get
Return _ConnectionString
End Get
Set(value As String)
_ConnectionString = value
OnPropertyChanged()
End Set
End Property
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Sub OnPropertyChanged(<CallerMemberName> Optional propertyName As String = Nothing)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
答案1
得分: 0
instrument 必须是一个属性,以便您可以绑定到它:
Public Property instrument As UnifaceModel
但您还需要在控件或其父窗口的某个地方设置DataContext:
Sub New()
' This call is required by the designer.
InitializeComponent()
' Set the DataContext to itself
DataContext = Me
' Add any initialization after the InitializeComponent() call.
FindUniface("uniface")
End Sub
由于您当前绑定到UserControl本身和instrument的属性,所以不应将DataContext绑定到instrument:
<WrapPanel Grid.Row="1">
<Label Name="PortName" Width="100" Content="{Binding instrument.ConnectionString}" HorizontalAlignment="Right"/>
<Label Name="ConStatus" Width="200" Content="{Binding UniName}" HorizontalAlignment="Left"/>
</WrapPanel>
英文:
instrument must be a property for you to be able to bind to it:
Public Property instrument As UnifaceModel
But you also need to set the DataContext of the control or its parent window somewhere:
Sub New()
' This call is required by the designer.
InitializeComponent()
' Set the DataContext to itself
DataContext = Me
' Add any initialization after the InitializeComponent() call.
FindUniface("uniface")
End Sub
Since you currently bind to properties of both UserControl itself and instrument, you should not bind the DataContext to instrument:
<WrapPanel Grid.Row="1">
<Label Name="PortName" Width="100" Content="{Binding instrument.ConnectionString}" HorizontalAlignment="Right"/>
<Label Name="ConStatus" Width="200" Content="{Binding UniName}" HorizontalAlignment="Left"/>
</WrapPanel>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论