转换器未转换回自定义用户控件内的Textbox unfocus,该控件具有到文本属性的双向绑定



我正在创建一个自定义的UWP用户控件。我用IValueConverter双向绑定TextBox中的文本,将字符串转换为十进制并返回。当从后面加载数据时,我的转换器正在将十进制转换为文本框中的字符串。然而,当Textbox在我的自定义控件内失去焦点时,我无法像常规Textbox控件的通常行为一样触发转换器的ConvertBack方法。

有没有一种方法可以注意到TextBox失焦,并通过其依赖属性触发转换回用户控件中的小数点,返回到模型数据?

这是我的UserControl。

<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失焦,并通过其依赖属性触发转换回我的用户控件中的小数点,返回到我的模型数据?

如果TextBox未聚焦,您可以订阅LostFocus事件进行侦听。然后在LostFocus事件中,您可以将textbox的当前值传递给Text依赖项属性,当Text属性的值更改时,它将触发conversion back方法,然后将小数返回到模型数据。

在您的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}"/>

最新更新