英文:
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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论