如果方法抛出异常,则更改文本块的前景 [英] Change Foreground of textblock if method throw an exception
问题描述
我有一个课程(从互联网上获取公共 IP)
i have a class (which get public ip from internet)
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 页面/视图中存在的文本块前景和字体粗细,如果我将其直接放在后面的代码中,则没有问题,我可以直接更改前景和字体粗细,但是会发生什么如果它是一个单独的类.我想要一个 mvvm 模式的答案,目前我在同一个类中得到 bool 结果
but problem is whenever it catch exception i need to change a textblock foreground and font weight present in Xaml page/View, if i put this directly in code behind there is no problem i can directly change foreground and fontweight but what will be the approach if it is a separate class.i want an answer in mvvm pattern currently i am getting bool result in same class
推荐答案
好的,下面是一些代码:
OK, here is some code:
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
}
要查看结果,请多次单击按钮...
To see results click more than once on the Button...
要连接视图和视图模型,您应该在实际项目中使用依赖注入或类似的东西...
To connect the View and the ViewModel you should use Dependency Injection or something like this in real world projects...
这篇关于如果方法抛出异常,则更改文本块的前景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!