WPF数据绑定:根据变量内容启用/禁用控件?

13

我在我的表单上有一个按钮,只有在树形视图(或选项卡中的列表视图)中选择项目时,该按钮才应启用。当选择一个项目时,其值将存储在字符串成员变量中。

我可以将按钮的 IsEnabled 属性绑定到成员变量的内容吗?也就是说,如果成员变量不为空,则启用该按钮。

类似地,当成员变量的内容更改(设置或清除)时,按钮的状态应更改。

3个回答

12

由于您可能希望根据一个字符串绑定按钮的IsEnabled属性,因此请尝试为其制作一个转换器。

也就是说...


<StackPanel>
<StackPanel.Resources>
<local:SomeStringConverter mystringtoboolconverter />
</StackPanel.Resources>
<Button IsEnabled="{Binding ElementName=mytree, Path=SelectedItem.Header, Converter={StaticResource mystringtoboolconverter}}" />
<StackPanel>
并且这是一个转换器:

[ValueConversion(typeof(string), typeof(bool))]
    class SomeStringConverter : IValueConverter {
        public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) {
            string myheader = (string)value;
            if(myhead == "something"){
                return true;
            } else {
                return false;
            }
        }
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) { return null; } }

编辑: 由于 OP 想要绑定到一个变量,需要做类似这样的事情:


public class SomeClass : INotifyPropertyChanged {
  private string _somestring;
public string SomeString{ get{return _somestring;} set{ _somestring = value; OnPropertyChanged("SomeString");} }
public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { if (this.PropertyChanged != null) { this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } }
}

这段代码定义了一个名为“SomeClass”的类,它实现了INotifyPropertyChanged接口。该类有一个私有字段"_somestring"和一个公共属性"SomeString",当该属性被设置时会触发"OnPropertyChanged"方法并引发"PropertyChanged"事件,通知其他对象属性已更改。

然后,将上面的绑定表达式更改为:

{Binding Path=SomeString, Converter={StaticResource mystringtoboolconverter}}

请注意,您必须实现INotifyPropertyChanged接口才能更新UI。


谢谢回复。 我在这行XAML代码里遇到了错误: <Grid.Resources> <local:StringToBoolConverter stringToBoolConverter /> </Grid.Resources> “找不到local:StringToBoolConverter的类型。” StringToBoolConverter是我的转换器类的名称。我需要使用命名空间来修饰它吗? - Number8
命名空间在XAML中出现问题。 - Number8
嗯,我认为这是不完整的;似乎需要通过成员属性引发某种事件,以便当成员属性更改时,按钮的启用状态也会更改。 - Number8
基本上,是的。当SelectedItem更改时,按钮的值也会更改。如果您想根据其他内容进行更改,请将其绑定到该内容。最重要的部分是将字符串绑定到按钮并使用转换器将其转换为布尔值。 - apandit
你需要在变量中添加OnPropertyChanged。我现在已经将其绑定到列表中的选择更改。如果你想要像这样的东西,var something = somethingnew; 并且在UI中反映出来,你需要将该变量设置为属性并实现INotifyPropertyChanged... 我会在我的帖子中添加这个。 - apandit
谢谢,OnPropertyChanged() 似乎是关键。看起来已经按预期工作了。 请注意,我的应用程序让用户选择以树形视图或选项卡视图查看数据。由于启用状态绑定到该变量,因此无论选择哪种视图,按钮都会正确更新。 感谢您的帮助... - Number8

9

您是否有一个 ViewModel,将其字符串属性设置为 View 的 DataContext,并在其中尝试进行此绑定?

那么以下内容将起作用:

  // Example ViewModel
public class MyClass : INotifyPropertyChanged
{
    private string text;

    public string Text
    {
        get { return text; }
        set 
        { 
            text = value;
            UpdateProperty("Text");
            UpdateProperty("HasContent");
        }
    }

    public bool HasContent
    {
        get { return !string.IsNullOrEmpty(text); }
    }


    public event PropertyChangedEventHandler PropertyChanged;

    protected void UpdateProperty(string name)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
}

那么你应该在视图的代码后台做出类似以下的操作:
this.DataContext = new MyClass();

以下是一个 Xaml 示例:

 <StackPanel>
        <TextBox Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}" />
        <Button IsEnabled="{Binding HasContent}">
            Click Me!
        </Button>
    </StackPanel>

字符串属性位于我的主窗口类中。 有没有办法让它在这种情况下工作?现在,HasContent()方法没有被调用;我怀疑这与DataContext没有设置有关。 - Number8
什么导致按钮调用HasContent()来设置其状态? 此外,我无法控制获取字符串值的控件。IsEnabled需要UpdateSourceTrigger属性吗? - Number8
如果窗口具有这些属性,您可以在Windows Loaded-Event中将其设置为自己的DataContext,如下所示: this.DataContext = this 然而,这是非常不好的做法。您应该考虑使用像我的示例中设置为DataContext的ViewModel。 注意HasContent不是一个方法,它是一个属性,因为只有属性才能绑定到视图。它的getter每次使用特定属性名称引发PropertyChanged时都会被评估。 UpdateSourceTrigger主要用于TextBox,以便在键入每个键时将其文本更改写回到绑定属性。否则,它们会在失去焦点时执行此操作。 - Andrej

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接