数据绑定到用户控件错误 Data.Binding 无法转换为 System.String

Data Binding to User Control Error Data.Binding cannot be converted to System.String

我是 WPF 新手,在将文本绑定到我创建的用户控件时遇到问题。这是一个简单的控件,它基本上只是一个带有文本和图像的按钮,我想在多个视图中重复使用它。

这是我的用户控件的 .cs

public partial class MenuItemUserControl : UserControl
{
    public string TextToDisplay { get; set; }

    public MenuItemUserControl()
    {
        InitializeComponent();
        DataContext = this;
    }
}

这是我的用户控件 xaml

<UserControl x:Class="Class.Controls.MenuItemUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Class.Controls"
             mc:Ignorable="d" 
             d:DesignHeight="83.33" d:DesignWidth="512">
    <Grid>
        <Button Style="{StaticResource MenuItemStyle}" Height="Auto" Width="Auto">
            <DockPanel LastChildFill="True" Width="512" Height="83.33" HorizontalAlignment="Center" VerticalAlignment="Center">
                <Image Source="/Resources/MenuArrow.png" Stretch="None" HorizontalAlignment="Left" VerticalAlignment="Center" DockPanel.Dock="Left"/>
                <TextBlock d:Text="sample" Text="{Binding TextToDisplay, Mode=OneWay}" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="{StaticResource MenuItems}"/>
            </DockPanel>
        </Button>
    </Grid>
</UserControl>

这是我的观点xaml

<Page x:Class="Class.Views.MenuOperate"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:uc="clr-namespace:Class.Controls"
      xmlns:local="clr-namespace:Class.Views"
      xmlns:properties="clr-namespace:Class.Properties"
      xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls" xmlns:viewmodels="clr-namespace:Class.ViewModels" d:DataContext="{d:DesignInstance Type=viewmodels:MenuOperateViewModel}"
      mc:Ignorable="d" 
      d:DesignHeight="500" d:DesignWidth="1024"
      Title="MenuOperate">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="83.33"/>
            <RowDefinition Height="83.33"/>
            <RowDefinition Height="83.33"/>
            <RowDefinition Height="83.33"/>
            <RowDefinition Height="83.33"/>
            <RowDefinition Height="83.33"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="512"/>
            <ColumnDefinition Width="512"/>
        </Grid.ColumnDefinitions>
        
        <uc:MenuItemUserControl TextToDisplay="{Binding StartStop, Mode=TwoWay}" Grid.Row="0" Grid.Column="0"/>
        </Grid>
</Page>

这是我的视图模型 .cs

namespace Class.ViewModels
{
    public class MenuOperateViewModel : ObservableObject
    {
        private string? _StartStop;

        public MenuOperateViewModel()
        {
            StartStop = Properties.Resources.MenuOperateStart;
        }

        public string? StartStop
        {
            get => _StartStop;
            set => SetProperty(ref _StartStop, value);
        }
    }
}

这是我在视图中遇到的错误 Xaml:

Object of Type 'System.Windows.Data.Binding' cannot be converted to type 'System.String'.

有两件事阻止了表达式

TextToDisplay="{Binding StartStop}"

有效。

  1. Binding 的目标 属性,即 TextToDisplay 必须是依赖 属性.

  2. 您不得显式设置 UserControl 的 DataContext。绑定将解析相对于当前 DataContext 的源 属性 路径,即在控件的构造函数中使用 DataContext = this;,它期望 UserControl 上的源 属性 StartStop,这是明显错了

详情见Data binding overview


您的代码应如下所示:

public partial class MenuItemUserControl : UserControl
{
    public static readonly DependencyProperty TextToDisplayProperty =
        DependencyProperty.Register(
            nameof(TextToDisplay),
            typeof(string),
            typeof(MenuItemUserControl));

    public string TextToDisplay
    {
        get { return (string)GetValue(TextToDisplayProperty); }
        set { SetValue(TextToDisplayProperty, value); }
    }

    public MenuItemUserControl()
    {
        InitializeComponent();
    }
}

UserControl 中的绑定 XAML 将使用 RelativeSource 绑定。

<TextBlock Text="{Binding TextToDisplay,
                  RelativeSource={RelativeSource AncestorType=UserControl}}" />