如果bool值为false,则只读取XAML Textbox

时间:2017-06-27 14:57:53

标签: wpf xaml

我的xaml中有一个文本框,用于从数据源中提取的ID字段。我希望此值只读,以便用户无法更改此值。我有一个按钮供用户添加一个新对象,当然需要一个ID。当我的对象“IsNew”在用户单击“添加新”按钮时设置为true时,我有一个bool属性。单击该按钮时,我希望此文本框可编辑。所以基本上,当“IsNew = true”时。我怎么能做到这一点?

//My Xaml for the textbox:
 <TextBox x:Name="ID"
                 Text="{Binding SelectedRecord.ID}"/>

//Xaml for the button
<Button x:Name="AddNewRecordButton"
              Grid.Column="1"
              Margin="20,0,5,0"
              HorizontalAlignment="Left"
              VerticalAlignment="Bottom"
              HorizontalContentAlignment="Left"
              Height="24"
              Width="90"
              Command="{Binding AddNewRecordCommand}"
              CommandParameter="{Binding ElementName=window}"/>

//Code for the command method
 public void AddNewRecord(object parameter)
{
  var newRecord = new StockingReason();
  Records.Add(newRecord);
  SelectedRecord = newRecord;
  newRecord.IsNew = true;
  var control = parameter as IFocusable;
  control?.SetFocus();
}

3 个答案:

答案 0 :(得分:1)

使用IValueConverter

public class InvertBoolConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool val = (bool)value;
        return !val;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool val = (bool)value;
        return !val;
    }
}

示例如何使用

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls"
        xmlns:local="clr-namespace:WpfApp1"
        xmlns:converter="clr-namespace:WpfApp1.MYCONVERTERNAMESPACE"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <converter:InvertBoolConverter x:Key="InvertBoolConverter" />
    </Window.Resources>

    <TextBox x:Name="ID"
             Text="{Binding SelectedRecord.ID}"
             IsReadOnly="{Binding IsNew, Converter={StaticResource InvertBoolConverter}}"/>

</Window>

答案 1 :(得分:0)

您可以使用Peter强调的 IValueConverter ,或者您也可以使用 WPF触发器

请参阅WPF Trigger binding to MVVM property

<TextBox>
        <TextBox.Style>
            <Style>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsNew}" Value="True">
                        <Setter Property="TextBox.IsReadOnly" Value="False" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding IsNew}" Value="False">
                        <Setter Property="TextBox.IsReadOnly" Value="True" />
                    </DataTrigger>

                    <Trigger Property="Control.IsMouseOver" Value="true">
                        <Setter Property="Control.FontStyle" Value="Italic"></Setter>
                        <Setter Property="Control.Foreground" Value="Red"></Setter>
                        <Setter Property="Control.Background" Value="Yellow"></Setter>
                    </Trigger>
                    <Trigger Property="Button.IsPressed" Value="true">
                        <Setter Property="Control.Foreground" Value="Green"></Setter>
                        <Setter Property="Control.Background" Value="Blue"></Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </TextBox.Style>
    </TextBox>

答案 2 :(得分:0)

所以我想如果我理解你的要求,你可以做到以下几点:

1)确保您的代码所在的类实现了INotifyPropertyChanged

2)在类上创建一个名为IsRecordReadOnly的新布尔属性,并使其转发所选记录IsNew Flag的反转。

3)在更新所选的选定记录后,在新的布尔属性上调用propertychanged。

4)将文本框上的IsReadOnly属性绑定到ViewModel中的IsRecordReadOnly属性。

public class ViewModel : INotifyPropertyChanged
    {
    private IRecord _selectedRecord;

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public List<IRecord> Records  = new List<IRecord>();

    public IRecord SelectedRecord
    {
        get { return _selectedRecord; }
        set
        {
            _selectedRecord = value;
            OnPropertyChanged();
        }
    }

    public bool IsRecordIdReadOnly
    {
        get { return !_selectedRecord?.IsNew ?? true; }
    }

    public void AddNewRecord(object parameter)
    {
        var newRecord = new StockingReason();
        Records.Add(newRecord);
        SelectedRecord = newRecord;
        newRecord.IsNew = true;
        var control = parameter as IFocusable;
        control?.SetFocus();
    }
}

然后你的xaml ......

<Grid>
    <TextBox x:Name="ID"
             Text="{Binding SelectedRecord.ID}" IsReadOnly="{Binding IsRecordReadOnly}"/>
</Grid>