我有一堂课(可以从互联网获取公共IP)
public class GetPublicIP
{
public string GetIPAddress()
{
string address = "";
try
{
WebRequest request = WebRequest.Create("http://checkip.dyndns.org/");
using (WebResponse response = request.GetResponse())
using (StreamReader stream = new StreamReader(response.GetResponseStream()))
{
address = stream.ReadToEnd();
}
int first = address.IndexOf("Address: ") + 9;
int last = address.LastIndexOf("</body>");
address = address.Substring(first, last - first);
}
catch (Exception)
{
address = "Click To Check On Browser";
//PublicIPTextBox.Foreground = new SolidColorBrush(Colors.IndianRed);
//PublicIPTextBox.FontWeight = FontWeights.SemiBold;
}
return address;
}
//Currently using this if its value is true i am changing foreground and fontweight in code behind
public bool ExceptionOccurs()
{
bool returning = false;
if (GetIPAddress() == "Click To Check On Browser")
returning = true;
return returning;
}
}
但是问题是,每当它捕获异常时,我都需要更改Xaml页面/视图中存在的textblock前景和字体粗细,如果直接将其放在代码后面,则没有问题,我可以直接更改前景和字体粗细,但是如果它是一个单独的类,则该方法。我想在mvvm模式中得到一个答案,我现在在同一个类中得到布尔结果
答案 0 :(得分:1)
好的,这是一些代码:
XAML:
<Window x:Class="WpfApp5.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:local="clr-namespace:WpfApp5"
mc:Ignorable="d"
WindowStartupLocation="CenterScreen"
SizeToContent="WidthAndHeight"
Title="MainWindow" Height="450" Width="800" d:DataContext="{d:DesignInstance local:MainWindowViewModel}">
<Grid Margin="10">
<StackPanel>
<Button Content="GetIP" Command="{Binding GetIpCommand}" Margin="5" Padding="5" />
<TextBox Text="{Binding IpAddress, Mode=OneWay}" Foreground="{Binding IpForeground}" Width="200" Margin="5"/>
</StackPanel>
</Grid>
</Window>
和代码:
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
DataContext = new MainWindowViewModel();
}
}
public class MainWindowViewModel : INotifyPropertyChanged {
private string _ipAdrress;
private bool _errorOccured;
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string IpAddress => _ipAdrress;
public Brush IpForeground => _errorOccured ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Colors.Black);
public ICommand GetIpCommand {
get { return new RelayCommand(param => DoExecuteGetIpCommand()); }
}
private async void DoExecuteGetIpCommand() {
try {
_errorOccured = false;
_ipAdrress = await MyService.GetIpAddress();
} catch (Exception ex) {
_errorOccured = true;
_ipAdrress = ex.Message;
}
OnPropertyChanged(nameof(IpAddress));
OnPropertyChanged(nameof(IpForeground));
}
}
internal class MyService {
private static bool _dummySucces = false;
public async static Task<string> GetIpAddress() {
//TODO Code to get IP in async manner...
_dummySucces = !_dummySucces;
if (!_dummySucces) {
throw new Exception("Error occured...");
}
return "1.1.1.1";
}
}
public class RelayCommand : ICommand {
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
/// <summary>
/// Creates a new command that can always execute.
/// </summary>
/// <param name="execute">The execution logic.</param>
public RelayCommand(Action<object> execute)
: this(execute, null) {
}
/// <summary>
/// Creates a new command.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
public RelayCommand(Action<object> execute, Predicate<object> canExecute) {
if (execute == null)
throw new ArgumentNullException("execute"); //NOTTOTRANS
_execute = execute;
_canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameter) {
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged {
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public void Execute(object parameter) {
_execute(parameter);
}
#endregion // ICommand Members
}
要查看结果,请在按钮上单击多次...
要连接View和ViewModel,您应该在实际项目中使用依赖注入或类似的方法...