C# WPF复选框已启用绑定
恐怕我有一个愚蠢的问题,我似乎找不到答案 我正在尝试为标签实现一个过滤器:它有一个文本框,您可以在其中输入标签,以及标记和未标记的复选框。如果文本框中有任何文本,我希望未标记的文本应该被禁用 我想这很容易: 我的ViewModel:C# WPF复选框已启用绑定,c#,wpf,xaml,C#,Wpf,Xaml,恐怕我有一个愚蠢的问题,我似乎找不到答案 我正在尝试为标签实现一个过滤器:它有一个文本框,您可以在其中输入标签,以及标记和未标记的复选框。如果文本框中有任何文本,我希望未标记的文本应该被禁用 我想这很容易: 我的ViewModel: private bool _untaggedEnabled = true; public UntaggedEnabled { get { return _untaggedEnabled; } set { _unta
private bool _untaggedEnabled = true;
public UntaggedEnabled {
get {
return _untaggedEnabled;
} set {
_untaggedEnabled = value;
OnPropertyChanged(nameof(UntaggedEnabled));
}
}
string _tagList;
public string TagList
{
get { return _tagList; }
set
{
_tagList = value;
OnPropertyChanged(); // [CallerMemberName]
OnPropertyChanged(nameof(IsUntaggedEnabled));
}
}
public bool IsUntaggedEnabled => TagList != "";
我的观点背后:
(是的,我可以单独在xaml中完成这项工作,但如果我擅长xaml,我就不会在这里了!)
我的看法是:
<TextBox x:Name="tagsList" Text="{Binding TagsList}" />
<CheckBox Content="Untagged" IsEnabled="{Binding UntaggedEnabled}" IsChecked="{Binding Untagged} />
如果文本框中有任何文本,则“未标记”应被禁用
在视图中无需任何代码即可轻松实现:
<TextBox Text="{Binding TagsList, UpdateSourceTrigger=PropertyChanged}" />
<CheckBox Content="Untagged" IsEnabled="{Binding IsUntaggedEnabled}"/>
如果文本框中有任何文本,则“未标记”应被禁用
在视图中无需任何代码即可轻松实现:
<TextBox Text="{Binding TagsList, UpdateSourceTrigger=PropertyChanged}" />
<CheckBox Content="Untagged" IsEnabled="{Binding IsUntaggedEnabled}"/>
绑定此ViewModel没有问题(并消除视图代码)
使用System.ComponentModel;
使用System.Runtime.CompilerServices;
公共类MainViewModel:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
受保护的布尔集合(参考T存储,T值,[CallerMemberName]字符串propertyName=null)
{
if(等于(存储,值))返回false;
储存=价值;
OnPropertyChanged(propertyName);
返回true;
}
字符串标记;
未标记的布尔;
公共字符串标记
{
获取=>\u标记;设置
{
if(设置(参考标记、值))
{
已更改的不动产(名称(未标记));
}
}
}
公共bool untaged{get=>_untaged;set=>set(ref _untaged,value);}
public bool untagedEnabled=>string.IsNullOrWhiteSpace(标记);
}
视图:
绑定此ViewModel没有问题(并去掉视图代码)
使用System.ComponentModel;
使用System.Runtime.CompilerServices;
公共类MainViewModel:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
受保护的布尔集合(参考T存储,T值,[CallerMemberName]字符串propertyName=null)
{
if(等于(存储,值))返回false;
储存=价值;
OnPropertyChanged(propertyName);
返回true;
}
字符串标记;
未标记的布尔;
公共字符串标记
{
获取=>\u标记;设置
{
if(设置(参考标记、值))
{
已更改的不动产(名称(未标记));
}
}
}
公共bool untaged{get=>_untaged;set=>set(ref _untaged,value);}
public bool untagedEnabled=>string.IsNullOrWhiteSpace(标记);
}
视图:
是否设置了?@链接?是-有许多其他控件都绑定到同一datacontext/VM,工作正常。文本框中没有事件声明:)@ValeraScherbakov-有,为了简洁起见,我没有显示它。请注意,问题是我可以将调试输出放在任何地方,并且除了复选框的可视状态之外,所有值都会按预期进行更新?只有事件不充分您是否设置了?@链接是-有许多其他控件都绑定到同一datacontext/VM,工作正常。TextBox中没有事件声明:)@ValeraScherbakov-有,为了简洁起见,我没有显示它。请注意,问题是我可以将调试输出放在任何地方,并且除了复选框的可视状态之外,所有值都会按预期进行更新?只有事件还不够,我已经实现了InotifyPropertyChanged,但是当我将OnPropertyChanged(nameof(untagedenabled))
添加到标记列表的setter中时,它起作用了。我不知道为什么该属性自己的setter没有处理它,但无论如何,我至少可以现在继续,即使我不完全理解。感谢您有两个viewmodel实例。一个是分配给views DataContext的,另一个是您在code behind(存储在_viewModel中)中设置属性的,我已经实现了InotifyPropertyChanged,但是当我将OnPropertyChanged(nameof(UntagedEnabled))
添加到TagsList
的setter中时,它起作用了。我不知道为什么该属性自己的setter没有处理它,但无论如何,我至少可以现在继续,即使我不完全理解。感谢您有两个viewmodel实例。一个指定给views DataContext,另一个是在代码隐藏(存储在_viewModel中)中设置属性的
using System.ComponentModel;
using System.Runtime.CompilerServices;
public class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged( [CallerMemberName] string propertyName = null )
{
PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( propertyName ) );
}
protected bool Set<T>( ref T storage, T value, [CallerMemberName] string propertyName = null )
{
if ( Equals( storage, value ) ) return false;
storage = value;
OnPropertyChanged( propertyName );
return true;
}
string _tags;
bool _untagged;
public string Tags
{
get => _tags; set
{
if ( Set( ref _tags, value ) )
{
OnPropertyChanged( nameof( UntaggedEnabled ) );
}
}
}
public bool Untagged { get => _untagged; set => Set( ref _untagged, value ); }
public bool UntaggedEnabled => string.IsNullOrWhiteSpace( Tags );
}
<TextBox
Text="{Binding Tags,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<CheckBox
Content="Untagged"
IsChecked="{Binding Untagged, Mode=TwoWay}"
IsEnabled="{Binding UntaggedEnabled, Mode=OneWay}"/>