我的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();
}
答案 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>