我正在编写简单的应用程序, 用户界面有两个文本框,用户名和用户名。密码和按钮提交信息。 我想使用路由命令而不是buttonclick事件。
用户名只能包含字母数字字符,如果用户输入任何其他特殊字符,则应显示输入无效字符的文本。 所以我想根据在Username文本框字段上完成的验证来绑定该文本块的可见性和内容。 任何人都可以帮我解决这个问题吗?
以下是我所制作的代码,但它没有按预期工作。任何人可以帮助我在哪里做错了吗?
在我的mainWindow.xaml下面
using System.Windows;
using System.Windows.Input;
using System.ComponentModel;
namespace ExcelUtility
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
ViewModel viewModelObj = new ViewModel();
public MainWindow()
{
InitializeComponent();
}
void navigatePageExecuted(object target, ExecutedRoutedEventArgs e)
{
SubmitUserDetails(txtUserName.Text + ";" + txtPassword);
}
void navigatePageCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (!string.IsNullOrWhiteSpace(txtUserName.Text))
{
viewModelObj.Username = txtUserName.Text;
}
e.CanExecute = viewModelObj.VaidUserName; }
private void SubmitUserDetails(string credentials)
{
this.Cursor = Cursors.Wait;
prgValidate.Visibility = Visibility.Visible;
MainGrid.IsEnabled = false;
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.RunWorkerAsync(credentials);
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
prgValidate.Visibility = Visibility.Collapsed;
string Result = (string)e.Result;
MessageBox.Show(Result); //Here I need to call some other functions based on return value for simplicity i have changed
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
string[] credentials = e.Argument.ToString().Split(';');
e.Result = viewModelObj.validateCredentials(credentials[0], credentials[1]);
}
}
}
这是我的xaml
<Window x:Class="ExcelUtility.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ExcelUtility"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:BoolToVisibleOrHidden x:Key="BoolToVisibilityConverter"/>
</Window.Resources>
<Window.CommandBindings>
<CommandBinding Command="{x:Static local:CommandsLibrary.navigatePageCommand}" Executed="navigatePageExecuted" CanExecute="navigatePageCanExecute"/>
</Window.CommandBindings>
<Grid Name="MainGrid">
<TextBlock Height="23" HorizontalAlignment="Left" Margin="40,44,0,0" Name="tbUserName" Text="Username" VerticalAlignment="Top" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="136,42,0,0" Name="txtUserName" VerticalAlignment="Top" Width="163" Text="{Binding Username, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="138,19,0,0" Name="tbNotify" Text="{Binding Notification, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="161" Visibility="{Binding NotVaidUserName,Converter={StaticResource BoolToVisibilityConverter}}" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="138,98,0,0" Name="txtPassword" VerticalAlignment="Top" Width="161" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="44,107,0,0" Name="tbPassword" Text="Password" VerticalAlignment="Top" Width="65" />
<Button Command="{x:Static local:CommandsLibrary.navigatePageCommand}" Content="Submit" Height="23" HorizontalAlignment="Left" Margin="172,167,0,0" Name="btnSubmit" VerticalAlignment="Top" Width="109" />
<ProgressBar Height="24" IsIndeterminate="True" Visibility="Collapsed" HorizontalAlignment="Left" Margin="52,232,0,0" Name="prgValidate" VerticalAlignment="Top" Width="257" />
</Grid>
这是我的viewModel
using System;
using System.Text.RegularExpressions;
using System.ComponentModel;
using System.Windows.Data;
using System.Windows;
namespace ExcelUtility
{
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool _notVaidUserName;
public bool NotVaidUserName
{
get { return _notVaidUserName; }
set
{
_notVaidUserName = value;
RaisePropertyChanged("NotVaidUserName");
}
}
private string notification;
public string Notification
{
get
{
return notification;
}
set
{
if (notification != value)
{
notification = value;
RaisePropertyChanged("Notification");
}
}
}
private string username;
public string Username
{
get
{
return username;
}
set
{
if (username != value)
{
username = value;
NotVaidUserName = VaidateUserName(username);
RaisePropertyChanged("Username");
}
}
}
public bool VaidateUserName(string strUsername)
{
bool bValidUserName = false;
if (!string.IsNullOrWhiteSpace(strUsername))
{
if (new Regex(@"^[a-zA-Z0-9]*$").IsMatch(strUsername))
{
bValidUserName = true;
if (strUsername.Length > 7)
{
Notification = "Max allowed key length is 6";
bValidUserName = false;
}
}
else
{
Notification = "No special characters allowed";
}
}
return bValidUserName;
}
public string validateCredentials(string Username, string Password)
{
return "Valid Credentials";
}
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
class BoolToVisibleOrHidden : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
object returnvalue = new object();
returnvalue = (bool)value ? Visibility.Visible : parameter != null ? Visibility.Collapsed : Visibility.Hidden;
return returnvalue;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (Visibility)value == Visibility.Visible;
}
}
}
非常感谢提前。 杜尔加
答案 0 :(得分:0)
您的代码无法正常工作的原因是您尚未为视图设置数据上下文。我喜欢在xaml中设置数据上下文,因为它会让你在VS中自动完成绑定指令。在根节点上,添加属性
DataContext="{Binding RelativeSource={RelativeSource Self}}"
这会将窗口本身设置为您的数据上下文,从而允许您的命令工作。但是,文本框上的绑定表达式将失败。您已在视图和ViewModel上拆分ViewModel逻辑。
我会将您的代码完全移到ViewModel中并使用
DataContext="{Binding RelativeSource={RelativeSource Self}, Path=ViewModel}"
作为数据上下文。那么你在视图后面的代码中唯一的代码就是
namespace ExcelUtility
{
public partial class MainWindow : Window
{
private ViewModel viewModel;
public MainWindow()
{
InitializeComponent();
}
public ViewModel ViewModel { get { return viewModel ?? (viewModel = new ViewModel()); } }
}
}
一旦绑定正常工作,您将不必在视图模型中设置UserName或Password(就像在navigatePageCanExecute和navigatePageExecuted方法中那样),因为绑定将为您设置它。 我不确定你的CommandsLibrary。你没有在示例中包含它。
这应该让你开始弄清楚其余部分。
我希望它有所帮助