C# 控件可见性与ViewModel属性的绑定不存在';行不通
我正在将一个相当大的WPF应用程序从三层转换为MVVM,并正在学习MVVM。到目前为止,我还没有深入研究绑定(等)的太多细节,所以请耐心听我说 我正在尝试将多个控件的System.Windows.Visibility绑定到ViewModel的公共属性(“状态”)。加载父选项卡项时,将根据需要读取和处理State属性。但是,在对特性进行后续更改时,这些更改似乎会被忽略。我(重新)检查了绑定,调试了转换器等等,这让我发疯 视图模型:C# 控件可见性与ViewModel属性的绑定不存在';行不通,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我正在将一个相当大的WPF应用程序从三层转换为MVVM,并正在学习MVVM。到目前为止,我还没有深入研究绑定(等)的太多细节,所以请耐心听我说 我正在尝试将多个控件的System.Windows.Visibility绑定到ViewModel的公共属性(“状态”)。加载父选项卡项时,将根据需要读取和处理State属性。但是,在对特性进行后续更改时,这些更改似乎会被忽略。我(重新)检查了绑定,调试了转换器等等,这让我发疯 视图模型: public class MarketingListViewMod
public class MarketingListViewModel: IDisposable, INotifyPropertyChanged
{
private UiState state;
public event PropertyChangedEventHandler PropertyChanged;
public UiState State
{
get { return state; }
set
{
if (state != value)
{
state = value;
NotifyPropertyChanged("State");
}
}
}
public MarketingListViewModel()
{
State = UiState.View;
}
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
视图:
有人知道为什么控件在状态更改后不更新其可见性吗
非常感谢
DPH
编辑--转换器:
[ValueConversion(typeof(WpfCrm.UiState), typeof(System.Windows.Visibility))]
public class EditStateToVisibilityConverter: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
UiState state = (UiState)value;
if (state == UiState.View) return Visibility.Collapsed;
else return Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
[ValueConversion(typeof(WpfCrm.UiState), typeof(System.Windows.Visibility))]
public class ViewStateToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
UiState state = (UiState)value;
if (state == UiState.View) return Visibility.Visible;
else return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
您似乎使用了视图模型的两个不同实例,一个在XAML中声明和使用
<UserControl.Resources>
<DPH:MarketingListViewModel x:Key="listVM" />
</UserControl.Resources>
<Grid DataContext="{StaticResource listVM}" >
当然,您应该只使用一个。因此,将您的代码隐藏声明更改为
listVM = (MarketingListViewModel)Resources["listVM"];
您似乎使用了视图模型的两个不同实例,一个在XAML中声明和使用
<UserControl.Resources>
<DPH:MarketingListViewModel x:Key="listVM" />
</UserControl.Resources>
<Grid DataContext="{StaticResource listVM}" >
当然,您应该只使用一个。因此,将您的代码隐藏声明更改为
listVM = (MarketingListViewModel)Resources["listVM"];
好的,有一个错误。您将listVM声明为
var listVM = new MarketingListViewModel();
但这不是XAML中的listVM。在XAML中,您创建了MarketingListViewModel的另一个实例。所以,当您尝试更改代码中声明的listVM时,什么也不会发生,因为该对象不是网格的DataContext
在单击处理程序中,必须编写以下内容:
private void buttonEditList_Click(object sender, RoutedEventArgs e)
{
var _listVM = (MarketingListViewModel)FindResource("listVM");
_listVM.State = UiState.Edit;
}
或者将代码隐藏中的listVM声明替换为以下声明:
listVM = (MarketingListViewModel)FindResource("listVM");
这样就不需要更改事件处理程序
希望有帮助。好的,有个错误。您将listVM声明为
var listVM = new MarketingListViewModel();
但这不是XAML中的listVM。在XAML中,您创建了MarketingListViewModel的另一个实例。所以,当您尝试更改代码中声明的listVM时,什么也不会发生,因为该对象不是网格的DataContext
在单击处理程序中,必须编写以下内容:
private void buttonEditList_Click(object sender, RoutedEventArgs e)
{
var _listVM = (MarketingListViewModel)FindResource("listVM");
_listVM.State = UiState.Edit;
}
或者将代码隐藏中的listVM声明替换为以下声明:
listVM = (MarketingListViewModel)FindResource("listVM");
这样就不需要更改事件处理程序
希望有帮助。刚刚添加的转换器代码是什么-谢谢!是否在代码隐藏的某个地方声明listVM?是--listVM=new MarketingListViewModel();--在视图构造函数中的InitializeComponent()之后。非常感谢大家!15个小时的头部撞击在10分钟内由SO解决。刚刚添加的转换器代码是什么-谢谢!是否在代码隐藏的某个地方声明listVM?是--listVM=new MarketingListViewModel();--在视图构造函数中的InitializeComponent()之后。非常感谢大家!15个小时的头痛在10分钟内就被SO解决了。我将把这个放在构造函数中,而不是创建一个新的VM@TonyVitabile你的意思是什么?最初的注释是“listVM=new MarketingListViewModel();--就在视图构造函数中InitializeComponent()之后”。我写了“在声明后面更改代码”,所以它显然也在构造函数中。我将把它放在构造函数中,以代替创建新声明的代码VM@TonyVitabile你的意思是什么?最初的注释是“listVM=new MarketingListViewModel();--就在视图构造函数中InitializeComponent()之后”。我写了“更改声明背后的代码”,所以它显然也在构造函数中。