Wpf 将元素绑定到不同的DataContext属性

Wpf 将元素绑定到不同的DataContext属性,wpf,xaml,data-binding,Wpf,Xaml,Data Binding,原谅这个问题-只是学习WPF,它让我的大脑受伤。无法理解绑定/数据上下文。下面的XAML是通过一些代码蒙克里生成的(我对WPF的了解不够好,不知道什么东西对发布有用): 因此,宽度和高度应该从main window.PanZoomController.ScaledWidth.填充。有人可以帮助实现这一点吗?请尽量少用XAML!?由于代码落后,我仍然需要保留该元素到s:ResizeThumb的绑定 编辑:回应ASh的建议。 我试着用我认为正确的方式改变,但仍然没有乐趣:( 简化的代码场景。相关代码

原谅这个问题-只是学习WPF,它让我的大脑受伤。无法理解绑定/数据上下文。下面的XAML是通过一些代码蒙克里生成的(我对WPF的了解不够好,不知道什么东西对发布有用):

因此,宽度和高度应该从
main window.PanZoomController.ScaledWidth.填充。
有人可以帮助实现这一点吗?请尽量少用XAML!?由于代码落后,我仍然需要保留该元素到
s:ResizeThumb
的绑定

编辑:回应ASh的建议。

我试着用我认为正确的方式改变,但仍然没有乐趣:(

简化的代码场景。相关代码隐藏:

Partial Public Class MainWindow

    Private _panZoomControl As New PanAndZoomController
    Public Property PanZoomController() As PanAndZoomController
        Get
            Return _panZoomControl
        End Get
        Set(ByVal value As PanAndZoomController)
            _panZoomControl = value
        End Set
    End Property

    Public Sub New()
        InitializeComponent()
    End Sub

    Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
        Me.DataContext = _panZoomControl
    End Sub

    Private Sub MousewheelMoved(sender As Object, e As MouseWheelEventArgs) Handles Me.MouseWheel
        _panZoomControl.ZoomFactor = zoomBorder.ZoomX
    End Sub

End Class

Public Class PanAndZoomController

    Private _zoomFactor As Double
    Public Property ZoomFactor() As Double
        Get
            Return _zoomFactor
        End Get
        Set(ByVal value As Double)
            _zoomFactor = value
            _scaledWidth = 10 * _zoomFactor
        End Set
    End Property

    Private _scaledWidth As Double = 10
    Public Property ScaledWidth() As Double
        Get
            Return _scaledWidth
        End Get
        Set(ByVal value As Double)
            _scaledWidth = value
        End Set
    End Property

End Class
Public Class Workspace
    Implements INotifyPropertyChanged

    Public Sub NotifyPropertyChanged(ByVal propName As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName))
    End Sub

    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

    Private _canvasZoomFactor As Double = 1
    Public Property CanvasZoomFactor() As Double
        Get
            Return _canvasZoomFactor
        End Get
        Set(ByVal value As Double)
            _canvasZoomFactor = value
            _handleWidth = 5 * value
            Me.NotifyPropertyChanged("HandleWidth")
        End Set
    End Property

    Private _handleWidth As Double = 5
    Public ReadOnly Property HandleWidth() As Double
        Get
            Return _handleWidth
        End Get
    End Property

End Class
XAML:


相关线路:

            <s:ResizeThumb Width="{Binding ElementName=Workspace, Path=HandleWidth,UpdateSourceTrigger=PropertyChanged}"

            Me.NotifyPropertyChanged("HandleWidth")
“我的理解是,目前这是ResizeThumb.vb的数据绑定”-不能用代码绑定到文件

每个绑定必须有一个源才能获取值。有一些选项可以提供该源:

  • 直接指定它,例如:
    “{Binding Source={StaticResource}}”

  • 使用DataContext-默认选项:
    “{Binding Path=SomeProperty}”
    -当没有提供源时,绑定将尝试在DataContext中查找请求的属性-与视图(或视图的一部分)关联的一些数据-可能需要在不同部分使用不同的数据。通常每个视图有一个DataContext(
    Me.DataContext=\u panZoomControl

  • 如果元素位于同一视图中,则使用其他元素作为绑定源(通过RelativeSource或ElementName)

  • s:ResizeThumb位于主窗口视图内,因此RelativeSource应该可以工作:

    <s:ResizeThumb Style="{StaticResource SliderThumbStyle}"  
                   Width="{Binding Path=PanZoomController.ScaledWidth, RelativeSource={RelativeSource AncestorType = {x:Type s:MainWindow}}}" 
                   Height="{Binding Path=PanZoomController.ScaledWidth, RelativeSource={RelativeSource AncestorType = {x:Type s:MainWindow}}}"
    

    除了@ASh关于如何实际绑定到属性的回答(+1)之外,您还应该在
    PanAndZoomController
    类中实现接口,以便在动态设置
    ZoomFactor
    ScaledWidth
    属性时刷新视图:

    Public Class PanAndZoomController
        Implements INotifyPropertyChanged
    
        Private _zoomFactor As Double
        Public Property ZoomFactor() As Double
            Get
                Return _zoomFactor
            End Get
            Set(ByVal value As Double)
                _zoomFactor = value
                NotifyPropertyChanged(NameOf(ZoomFactor))
                ScaledWidth = 10 * _zoomFactor
            End Set
        End Property
    
        Private _scaledWidth As Double = 10
        Public Property ScaledWidth() As Double
            Get
                Return _scaledWidth
            End Get
            Set(ByVal value As Double)
                _scaledWidth = value
                NotifyPropertyChanged(NameOf(ScaledWidth))
            End Set
        End Property
    
        Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    
        Protected Sub NotifyPropertyChanged(info As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
        End Sub
    End Class     
    

    感谢您的详细回复,Ash。我仍然有很多阅读和调整要做。您的代码通过设置默认值
    ScaledWidth
    并查看它在布局中的反映,开始进行了良好的测试。但是,当我更改此属性时,它在布局中不会更改(保持相同的值)。关于如何使其真正动态化还有什么建议吗?@stigzler,请阅读INotifyPropertyChanged接口,在PanAndZoomController类中实现它,并从setters(对于ZoomFactor和ScaledWidth)引发PropertyChanged事件以通知视图(绑定)关于数据更改。我不擅长vb.net编写示例:\n再次感谢您的回复,ash。我厌倦了您使用
    INotify
    更新的代码,但仍然没有乐趣。此后我更新了我的原始帖子,以提供一个更简单的代码大纲,以及我尝试使用
    INotify
    的内容-任何其他建议-这让我感到兴奋uts!
                <s:ResizeThumb Width="{Binding ElementName=Workspace, Path=HandleWidth,UpdateSourceTrigger=PropertyChanged}"
    
                Me.NotifyPropertyChanged("HandleWidth")
    
    <s:ResizeThumb Style="{StaticResource SliderThumbStyle}"  
                   Width="{Binding Path=PanZoomController.ScaledWidth, RelativeSource={RelativeSource AncestorType = {x:Type s:MainWindow}}}" 
                   Height="{Binding Path=PanZoomController.ScaledWidth, RelativeSource={RelativeSource AncestorType = {x:Type s:MainWindow}}}"
    
    Public Class PanAndZoomController
        Implements INotifyPropertyChanged
    
        Private _zoomFactor As Double
        Public Property ZoomFactor() As Double
            Get
                Return _zoomFactor
            End Get
            Set(ByVal value As Double)
                _zoomFactor = value
                NotifyPropertyChanged(NameOf(ZoomFactor))
                ScaledWidth = 10 * _zoomFactor
            End Set
        End Property
    
        Private _scaledWidth As Double = 10
        Public Property ScaledWidth() As Double
            Get
                Return _scaledWidth
            End Get
            Set(ByVal value As Double)
                _scaledWidth = value
                NotifyPropertyChanged(NameOf(ScaledWidth))
            End Set
        End Property
    
        Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    
        Protected Sub NotifyPropertyChanged(info As String)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
        End Sub
    End Class