c# - ViewModel 中属性的 BindingExpression 路径错误

标签 c# wpf xaml binding

我有以下抛出的可见性绑定(bind):

System.Windows.Data Error: 40 : BindingExpression path error: 'Vis' property not found on 'object' ''LoginViewModel' (HashCode=22943289)'. BindingExpression:Path=Vis; DataItem='LoginViewModel' (HashCode=22943289); target element is 'Login' (Name=''); target property is 'Visibility' (type 'Visibility')

看不出我做错了什么,该属性确实存在于 MainViewModel 中。也许我正在以错误的方式展示和隐藏这一点。

<Window x:Class="Bt.MainWindow"
        xmlns:vm="clr-namespace:Bt"
        xmlns:ctrls="clr-namespace:Bt.Controls">

    <Window.DataContext>
        <vm:MainViewModel x:Name="MWin" />
    </Window.DataContext>

    <Grid>
        <ctrls:Login Visibility="{Binding Vis}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></ctrls:Login>
    </Grid>
</Window>

View 模型:

namespace Bt
{
    class MainViewModel : INotifyPropertyChanged
    {
        public MainViewModel()
        {
            Vis = "Collapsed";
        }

        private string _vis = "Collapsed";
        public string Vis
        {
            get { return _vis; }
            set
            {
                    _vis = value;
                    RaisePropertyChanged("Vis");
            }
        }
    }
}


[编辑]当用户控件的可见性在主窗口中发生更改时,在用户控件内部进行捕获。

我意识到转换器没有被正确调用,因此可能还需要一些帮助。至于其余的,希望你能看到我想要实现的目标。

查看:

<UserControl x:Class="Bt.Controls.Login" 
             xmlns:app="clr-namespace:Bt" 
             xmlns:viewmodel="clr-namespace:Bt.Controls"
             mc:Ignorable="d"
             Visibility="{Binding Visi,Converter={StaticResource BooleanToVisibilityConverter}}"
            >
</UserControl>

查看模型:

namespace Bt.Controls
{
    class LoginViewModel : INotifyPropertyChanged
    {
        public LoginViewModel(){}

        private bool _visi = true;
        public bool Visi
        {
            get { return _visi; }
            set
            {
                _visi = value;
                RaisePropertyChanged("Visi");
                MessageBox.Show("Visi set");
                reset_timer(_visi);
            }
        }
    }

    [ValueConversion(typeof(bool), typeof(Visibility))]
    public class VisibilityConverter : IValueConverter
    {
        public const string Invert = "Invert";

        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            if (targetType != typeof(Visibility))
                throw new InvalidOperationException("The target must be a Visibility.");

            bool? bValue = (bool?)value;

            if (parameter != null && parameter as string == Invert)
                bValue = !bValue;

            return bValue.HasValue && bValue.Value ? Visibility.Visible : Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            return ((value is Visibility) && (((Visibility)value) == Visibility.Visible));
        }
        #endregion
    }
}

最佳答案

从错误中可以明显看出,BindingEngine 正在 LoginViewModel 中查找属性 Vis,而不是在 MainViewModel 中。 (您必须将登录用户控件的 DataContext 设置为 LoginViewModel)。

您需要获取 Window 的 DataContext,您可以使用 RelativeSource 获取它:

<ctrls:Login Visibility="{Binding DataContext.Vis,
       RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/>

此外,您还应该将 Vis 创建为 bool 并在绑定(bind)中使用 BooleanToVisibility 转换器。

<Grid>
    <Grid.Resources>
       <BooleanToVisibilityConverter x:Key="BooelanToVisibilityConverter"/>
    </Grid.Resources>
    <ctrls:Login Visibility="{Binding DataContext.Vis,
                           RelativeSource={RelativeSource Mode=FindAncestor,
                                                          AncestorType=Window}}",
                         Converter={StaticResource BooelanToVisibilityConverter}
                 HorizontalAlignment="Stretch" 
                 VerticalAlignment="Stretch"/>
</Grid>

不鼓励在 ViewModel 中使用 Visibility 属性,因为它是 View 的东西,不应该出现在 ViewModel 中。拥有 bool 是完全可以的,您可以随时使用转换器进行转换。

关于c# - ViewModel 中属性的 BindingExpression 路径错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21720972/

相关文章:

c# - WCF 消耗多个可能的 REST 响应

c# - System.Timers.Timer 稳步增加间隔

c# - 在WPF中保存控件的图像(屏幕截图) - MVVM模式

wpf - 引用资源字典的正确方法是什么?

c# - LongListSelector 停止滚动并卡住

c# - 如何通过 C# 在 Excel 中将公式值解析为文本

c# - C# 中的 WPF 类型初始化异常

c# - WPF 内存泄漏

c# - 代码隐藏中的 Datagrid 绑定(bind)与 XAML 中的 DataGrid 绑定(bind)

c# - Moq:使用 FluentValidation 运行流程