WPF XAML中无需x:Name,能否绑定ViewModel属性到Converter的DependencyProperty?
WPF转换器依赖属性绑定ViewModel属性(无需x:Name)
问题描述
尝试将SampleViewModel的A属性绑定至SampleConverter中作为DependencyProperty的B属性时出现XAML绑定错误,且转换器的DataContext显示为null。已知通过x:Name可获取目标DataContext,但希望不借助x:Name实现该绑定;另外使用RelativeSource仅能获取SampleConverter自身的上下文,无法访问其他对象的DataContext。
原始XAML代码:
<Window x:Class="WpfApp1.BindPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApp1" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Window.DataContext> <local:SampleViewModel /> </Window.DataContext> <StackPanel> <StackPanel.Height> <Binding Path="ActualWidth" RelativeSource="{RelativeSource Mode=Self}"> <Binding.Converter> <local:SampleConverter B="{Binding A}" /> </Binding.Converter> </Binding> </StackPanel.Height> </StackPanel> </Window>
解决方案
方法1:通过RelativeSource查找上级Window的DataContext
转换器作为Binding的子对象,默认不会继承上级元素的DataContext,但可以通过RelativeSource向上查找父级Window,直接绑定其DataContext下的属性。修改后的代码如下:
<Window x:Class="WpfApp1.BindPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApp1" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Window.DataContext> <local:SampleViewModel /> </Window.DataContext> <StackPanel> <StackPanel.Height> <Binding Path="ActualWidth" RelativeSource="{RelativeSource Mode=Self}"> <Binding.Converter> <!-- 通过FindAncestor找到Window,绑定其DataContext.A --> <local:SampleConverter B="{Binding DataContext.A, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" /> </Binding.Converter> </Binding> </StackPanel.Height> </StackPanel> </Window>
方法2:将ViewModel定义为静态资源并直接绑定
如果把SampleViewModel注册为Window的静态资源,可以直接通过Source={StaticResource}指定绑定源,无需依赖元素名称:
<Window x:Class="WpfApp1.BindPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApp1" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <!-- 将ViewModel注册为静态资源 --> <Window.Resources> <local:SampleViewModel x:Key="SampleVM" /> </Window.Resources> <Window.DataContext> <StaticResource ResourceKey="SampleVM" /> </Window.DataContext> <StackPanel> <StackPanel.Height> <Binding Path="ActualWidth" RelativeSource="{RelativeSource Mode=Self}"> <Binding.Converter> <!-- 直接绑定静态资源中的ViewModel属性 --> <local:SampleConverter B="{Binding A, Source={StaticResource SampleVM}}" /> </Binding.Converter> </Binding> </StackPanel.Height> </StackPanel> </Window>
关键说明
转换器实例是Binding的内部对象,默认不会继承外部元素的DataContext,因此必须显式指定绑定源。上述两种方法均通过指定明确的绑定源(上级Window的DataContext或全局静态资源)实现了无需x:Name的绑定需求。
内容的提问来源于stack exchange,提问作者cjk
相关产品推荐
相关产品推荐

