我有一个简单的数据页面,用户填写2个字段(名字和姓氏),然后点击AppBarButton
上的保存CommandBar
。
这两个字段都使用x:Bind
和Mode=TwoWay
来加载/更新值。
如果用户填写文本框中的名字,则填写姓氏的文本框并点击CommandBar上的Save AppBarButton,而焦点仍在Last Name文本框中,只更新第一个名称。 / p>
但是,我还在页面上创建了常规Button
,如果用户执行相同操作并使用此按钮,则两个字段都会按预期更新。
如何让CommandBar上的AppBarButton以与常规按钮相同的方式工作并更新所有数据而不添加大量代码?
这是我的简单类定义:
public class UserData
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
这是XAML页面:
<Page
x:Class="mySampleApp.MainPage"
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"
x:Name="MyPage"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<CommandBar Grid.Row="0" DefaultLabelPosition="Right" >
<!-- Save button on a command bar-->
<AppBarButton Icon="Save" Label="Save" LabelPosition="Default" Click="saveStuff_Click" />
</CommandBar>
<!-- Sample Data to save-->
<TextBox x:Name="txtFirstName" Grid.Row="1" Header="Enter Your First Name" Text="{x:Bind currentUserData.FirstName, Mode=TwoWay}" PlaceholderText="First Name"/>
<TextBox x:Name="txtLastName" Grid.Row="2" Header="Enter Your Last Name" Text="{x:Bind currentUserData.LastName, Mode=TwoWay}" PlaceholderText="Last Name"/>
<!-- Save button using a regular button that calls the same function-->
<Button x:Name="saveStuff" Grid.Row="3" Content="Save" Click="saveStuff_Click" />
</Grid>
</Page>
这是背后的代码:
using Newtonsoft.Json;
using System;
using Windows.Storage;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace mySampleApp
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
//variables to use in XAML x:Bind
private UserData currentUserData = new UserData();
public MainPage()
{
this.InitializeComponent();
}
private async void saveStuff_Click(object sender, RoutedEventArgs e)
{
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("sampledata.json", CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(file, JsonConvert.SerializeObject(currentUserData, Formatting.Indented));
var dialog = new MessageDialog("Data saved to: " + file.Path.ToString() + Environment.NewLine + "Data Saved: FirstName: " + currentUserData.FirstName + "; LastName: " + currentUserData.LastName);
await dialog.ShowAsync();
}
}
}
答案 0 :(得分:4)
我能够通过保留所有文本框绑定(使用<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
)并仅使用x:Bind
更新AppBarButton
上的CommandBar
来解决此问题。
现在它看起来像这样,一切都按预期工作:
AllowFocusOnInteraction="True"
答案 1 :(得分:1)
正如in the official documentation (scroll down to UpdateSourceTrigger)
所述,x:Bind
上的TextBox.Text
等待文本框失去焦点,将其内容转发给Viewodel。与从文本框中窃取上下文的普通Button
相比,似乎在使用AppBarButton
时焦点停留在文本框上(正如您自己提到的),因此绑定属性永远不会更新
将绑定的UpdateSourceTrigger
设置为PropertyChanged
可能会解决问题,因为它强制在每次按键时刷新bindig,但不幸的是x:Bind
不支持。所以我猜你最好选择使用传统的Binding
:
Text="{Binding currentUserData.LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"