基于文本框内容更改WPF控件(按钮)的已启用属性
本文关键字:WPF 按钮 控件 属性 启用 于文本 文本 | 更新日期: 2023-09-27 18:21:28
我正在WPF中寻找一个解决方案,根据文本框的内容更改按钮的IsEnabled属性。TextBox包含一个数值。如果该值大于某个值,则按钮的IsEnabled属性应设置为true,只要该值低于该值,则该属性应为false。我一直在四处寻找,但找不到合适的解决方案。我在CodeProject上找到的几乎就是我想要的。但问题是,这种方法只是检查文本框中是否有任何内容。但我需要检查/比较数字内容。
我更愿意在XAML中找到一种方法。或者,我也可以在ViewModel中实现它。但是我不知道怎么做!我想通过文本框中显示的属性中的INotifyChanged事件通知按钮。但我不知道是怎么回事。
遵循了一些代码。但是,对不起,文本框和按钮旁边什么都没有,因为我找不到解决这个问题的方法。
<TextBox Name ="tbCounter" Text ="{Binding CalcViewModel.Counter, Mode=OneWay}" Background="LightGray" BorderBrush="Black" BorderThickness="1"
Height="25" Width="50"
commonWPF:CTextBoxMaskBehavior.Mask="Integer"
commonWPF:CTextBoxMaskBehavior.MinimumValue="0"
commonWPF:CTextBoxMaskBehavior.MaximumValue="1000"
IsReadOnly="True"/>
<Button Name="btnResetCount" Focusable="True" Content="Reset" Command="{Binding Path=CalcViewModel.ResetCounter}" Style="{StaticResource myBtnStyle}"
Width="100" Height="25">
有没有一种常见的方法可以基于XAML或ViewModel中的属性/值设置控件的IsEnabled属性?
EDIT这是我的ViewModel,我提取了相关的成员和属性,否则帖子会太长:
class CalcViewModel:INotifyPropertyChanged
{
private CCalc _calc;
public int Counter
{
get
{ return _calc.Counter; }
set{ _calc.Counter = value;}
}
public event PropertyChangedEventHandler PropertyChanged;
void ResetCounterExecute()
{ _calc.Counter = 0; }
bool CanResetCounterExecute()
{
if (_calc.Counter > 0)
{ return true; }
else
{ return false; }
}
public ICommand ResetCounter
{ get { return new RelayCommand(ResetCounterExecute, CanResetCounterExecute); } }
public CCalcViewModel()
{
this._calc = new CCalcViewModel();
this._calc.PropertyChanged += new PropertyChangedEventHandler(OnCalcPropertyChanged);
}
private void OnCalcPropertyChanged(object sender, PropertyChangedEventArgs e)
{
this.RaisePropertyChanged(e.PropertyName);
}
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
您想要组合元素属性绑定:
IsEnabled={Binding ElementName=Textbox, Path=Text}
带值转换器
IsEnabled={Binding ElementName=Textbox, Path=Text, Converter={StaticResource IsAtLeastValueConverter}}
IsAtLeastValueConverter.cs
namespace WpfPlayground
{
public class IsAtLeastValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (System.Convert.ToInt32(value) > 5)
{
return true;
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return Binding.DoNothing;
}
}
}
哦,我忘了你需要把这个添加到你的控制中:
<Window.Resources>
<wpfPlayground:IsAtLeastValueConverter x:Key="IsAtLeastValueConverter" />
</Window.Resources>
编辑:VM版本
我已经放入了省略(…),其中我没有对您的代码进行更改。
<Button ... IsEnabled={Binding Path=ButtonIsEnabled} ...>
class CalcViewModel:INotifyPropertyChanged
{
private CCalc _calc;
private bool _buttonIsEnabled;
public ButtonIsEnabled {
get { return _buttonIsEnabled; }
set {
_buttonIsEnabled = value;
RaisePropertyChanged("ButtonIsEnabled");
}
}
public int Counter
{
get
{ return _calc.Counter; }
set{
_calc.Counter = value;
_buttonIsEnabled = _calc.Counter > 5;
}
}
...
}
因此,当您更改计数器值时,您会设置ButtonIsEnabled属性,该属性会引发属性更改事件,并使用您正在使用的任何逻辑更新表单上的按钮,以确定是否应启用该按钮。
编辑:您可能需要从文本框中删除Binding=OneWay,我不确定如果您使用该设置,它是否会启动set属性。
如果你想直接在XAML中进行验证(我不一定建议这样做,因为验证可能应该在视图模型中进行),你也可以使用一个包,比如https://quickconverter.codeplex.com/-这允许您在绑定中编写一些C#(ish)。
我以前用过它,它可以让它变得非常容易,例如你安装软件包,在应用程序的一开始就添加一行:
QuickConverter.EquationTokenizer.AddNamespace(typeof(object));
它将系统名称空间添加到QuickConverter(上面的行作为对象在系统名称空间中),然后您可以简单地执行:
IsEnabled="{qc:Binding 'Int32.TryParse($P) && Int32.Parse($P) >= 3', P={Binding ElementName=tbCounter, Path=Text}}"
如果&
破坏了你的Intellisense,你可以改为写:
IsEnabled="{qc:Binding 'Int32.TryParse($P) ## Int32.Parse($P) >= 3', P={Binding ElementName=tbCounter, Path=Text}}"
(其中3
是您测试的值)。
编辑:
对不起,在重读XAML时,它可以更直接地写如下:
IsEnabled="{qc:Binding '$P >= 3', P={Binding CalcViewModel.Counter}}"
您应该将ViewModel更改为类似的内容
public class ViewModel:INotifyPropertyChanged
{
public int Counter
{
get { return _counter; }
set {
_counter = value;
RaisePropChanged("Counter");
//for example
if (value>3)
{
IsButtonCounterEnabled = true;
}
else
{
IsButtonCounterEnabled = false;
}
}
}
public bool IsButtonCounterEnabled
{
get { return _IsButtonCounterEnabled; }
set { _IsButtonCounterEnabled = value;
RaisePropChanged("IsButtonCounterEnabled");
}
}
private void RaisePropChanged(string propName)
{
PropertyChanged(this,new PropertyChangedEventArgs(propName));
}
public event PropertyChangedEventHandler PropertyChanged = delegate{};
private int _counter;
private bool _IsButtonCounterEnabled;
}
然后像这个一样绑定你的按钮
<Button IsEnabled="{Binding IsButtonCounterEnabled,Mode=OneWay}" Content="Button" HorizontalAlignment="Left" Height="47" Margin="215,57,0,0" VerticalAlignment="Top" Width="159"/>
希望这能帮助