我有以下抛出的可见性绑定(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/