c# - 转换器未通过两种方式绑定到文本属性的自定义用户控件内的文本框取消焦点转换回
问题描述
我正在创建一个自定义 UWP 用户控件。我有两种方法将 TextBox 中的文本与 IValueConverter 绑定,以将字符串转换为十进制并返回。从后面加载数据时,我的转换器正在将十进制转换为文本框中的字符串。但是,当文本框在我的自定义控件中失去焦点时,我无法触发转换器的 ConvertBack 方法,就像常规文本框控件的通常行为一样。
有没有办法注意到 TextBox unfocus 并通过它的依赖属性触发转换回我的用户控件内的小数回到我的模型数据?
这是我的用户控件。
<UserControl
<Grid Margin="15,0,15,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="5*"/>
</Grid.ColumnDefinitions>
<TextBox
x:Name="textBox"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
Header="{x:Bind Header}"
Text="{x:Bind Text}"
IsEnabled="{x:Bind IsControlEnabled}"/>
<TextBlock
Grid.Row="1"
Grid.Column="0"
Foreground="RosyBrown"
Text="{x:Bind InspectionValidation}"/>
</Grid>
</UserControl>
这是它的代码隐藏
public sealed partial class FrmTextBox : UserControl, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register("Header", typeof(string),
typeof(FrmComboBox), new PropertyMetadata(null));
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string),
typeof(FrmComboBox), new PropertyMetadata(null));
public static readonly DependencyProperty
InspectionValidationProperty =
DependencyProperty.Register("InspectionValidation", typeof(string)
, typeof(FrmInspection), null);
public static readonly DependencyProperty
IsLayoutEnabledProperty =
DependencyProperty.Register("IsLayoutEnabled", typeof(int?)
, typeof(FrmInspection), null);
public string Header
{
get { return (string)GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set
{
SetValue(TextProperty, value);
}
}
public string InspectionValidation
{
get => (string) GetValue(InspectionValidationProperty);
set =>SetValue( InspectionValidationProperty, value);
}
public int? IsLayoutEnabled
{
get => (int?) GetValue(IsLayoutEnabledProperty);
set
{
IsControlEnabled = (value == -1) ? true : false;
SetValue( IsLayoutEnabledProperty, value);
}
}
private bool isControlEnabled { get; set; }
public bool IsControlEnabled
{
get => isControlEnabled;
set
{
if (value == isControlEnabled) return;
isControlEnabled = value;
OnPropertyChanged();
}
}
public FrmTextBox()
{
this.InitializeComponent();
}
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
// Raise the PropertyChanged event, passing the name of the property whose value has changed.
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
这是我的 IValueConverter
public class StringToDecimalConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value != null)
return value.ToString();
return string.Empty;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
try
{
if (value != null)
{
Decimal newValue;
Decimal.TryParse((string) value, out newValue);
return newValue;
}
return null;
}
catch
{
return null;
}
}
}
这是我的用户控件的 Xaml 实现。
<controls:FrmTextBox
Grid.Row="1"
Grid.Column="1"
Header="Labor Count"
Text="{x:Bind ViewModel.Current.LaborCount, Mode=TwoWay, Converter={StaticResource StringToDecimal}}"
InspectionValidation=""
IsLayoutEnabled="-1">
</controls:FrmTextBox>
解决方案
有没有办法注意到 TextBox unfocus 并通过它的依赖属性触发转换回我的用户控件内的小数回到我的模型数据?
如果 TextBox 未获得焦点,您可以订阅 LostFocus 事件来监听。然后在 LostFocus 事件中,您可以将 textbox 的当前值传递给您的 Text 依赖属性,当 Text 属性的值发生变化时,它会触发转换返回方法,然后将小数返回给您的模型数据。
在您的 usercontrol.xaml 中:
<TextBox
x:Name="textBox"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
Header="{x:Bind Header}"
Text="{x:Bind Text}"
IsEnabled="{x:Bind IsControlEnabled}" LostFocus="textBox_LostFocus"/>
在您的 usercontrol.cs 中:
......
private void textBox_LostFocus(object sender, RoutedEventArgs e)
{
Text = textBox.Text;
}
或者直接将你的文本框的绑定模型设置为Twoway。
在您的 usercontrol.xaml 中:
<TextBox
x:Name="textBox"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
Header="{x:Bind Header}"
Text="{x:Bind Text,Mode=TwoWay}"
IsEnabled="{x:Bind IsControlEnabled}"/>
推荐阅读
- excel - 在目录的 Excel 中提供文件列表会减慢 excel
- php - mpdf 在 cli 中有效,但在浏览器中无效
- python - 字典键字符串
- java - Project Reactor:我需要处理器吗?
- javascript - 在节点中使用 Arguments 对象时,箭头函数中的行为不正确
- blender - 如何在 Blender 中将对象的每个断裂导出到单独的 .obj 文件中?
- laravel - 恢复链接到另一个类别 Laravel 的类别的 slug
- scala - 从受自我类型约束的多个特征中定义一个特征
- jquery - 首先单击 selectpicker 的最后选择的选项将不起作用
- c++ - 如何修复程序上的错误以衡量性能