WPF的新手,试图弄清楚为什么StatusBar的样式更改不能正常工作。代码似乎非常简单:
private void OnTryP4Login(object sender, RoutedEventArgs e)
{
statusText.Text = string.Format("Connecting to {0} as '{1}'.",
textBoxUri.Text, textBoxUser.Text); // <-- Doesn't work
statusBar.Background = Brushes.Yellow; // <-- Doesn't work
if (m_Manager.P4Login(textBoxUri.Text, textBoxUser.Text,
textBoxClientSpec.Text, passwordBox.Password))
{
statusText.Text = "SUCCESS!"; // <-- Doesn't work
statusBar.Background = Brushes.Green; // <-- Doesn't work
Thread.Sleep(2000);
this.Close();
}
else
{
statusBar.Background = Brushes.Red; // <-- THIS works
statusText.Text = "Error connecting to Perforce server!"; // <-- THIS works
buttonConnect.Visibility = Visibility.Collapsed;
buttonOK.Visibility = Visibility.Visible;
}
}
有人可以用我的方式向我显示错误吗?
相关的XAML:
<Window x:Class="WpfClient.P4LoginDialog"
[...]
Icon="feat.ico">
<DockPanel>
<Grid DockPanel.Dock="Top" Height="158">
[...]
<Button x:Name="buttonConnect" Content="Connect" Click="OnTryP4Login" HorizontalAlignment="Left" Margin="274,130,0,-18" VerticalAlignment="Top" Width="75"/>
</Grid>
<StatusBar x:Name="statusBar" Height="25" Background="#888" DockPanel.Dock="Bottom" HorizontalAlignment="Stretch" >
<TextBlock x:Name="statusText"
Width="Auto"
Height="Auto"
Foreground="#fff"
Text="Connect to P4 for live integration"
HorizontalAlignment="Right"
TextAlignment="Right"
/>
</StatusBar>
</DockPanel>
更新:感谢这些建议,我们可以通过以下方式让黄色文字正常工作。绿色成功消息仍然没有运气。为了完全理解执行流程以及建议完全意味着什么(上次我做了这样的事情,BackgroundWorkers风靡一时),我得到了一大堆关于异步的阅读。我感谢任何其他提示/解释。
private async void OnTryP4Login(object sender, RoutedEventArgs e)
{
statusText.Text = string.Format("Connecting to {0} as '{1}'.",
textBoxUri.Text, textBoxUser.Text); // <-- Works now
statusBar.Background = Brushes.DarkGoldenrod; // <-- Works now
Task<bool> getConnection = m_Manager.P4Login(textBoxUri.Text, textBoxUser.Text, textBoxClientSpec.Text, passwordBox.Password);
bool connection = await getConnection;
if (connection)
{
statusText.Text = "SUCCESS!"; // <-- Still doesn't work (stays DarkGoldenrod)
statusBar.Background = Brushes.Green; // <-- Still doesn't work (stays DarkGoldenrod)
Thread.Sleep(2000);
this.Close();
}
else
{
statusBar.Background = Brushes.Red; // <-- Still works
statusText.Text = "Error connecting to Perforce server!"; // <-- Still works
buttonConnect.Visibility = Visibility.Collapsed;
buttonOK.Visibility = Visibility.Visible;
}
}
public async Task<bool> P4Login(string uri, string user, string clientSpec, string password)
{
await Task.Delay(100);
return m_PI.Connect(uri, user, clientSpec, password);
}
答案 0 :(得分:2)
在单线程应用程序中,对控件的更新不会产生影响,直到您的事件处理程序完成并且屏幕可以更新。您的Thread.Sleep(2000);
会屏蔽整个用户界面。
制作方法async
并用await Task.Delay( 2000 )
替换睡眠。这将允许正常事件循环在这两秒内接管,UI将更新。
编辑:您的“正在连接”和黄色背景仍无法正常工作,因为(我认为)m_Manager.P4Login()
是一个同步功能。如果您无法使其异步,请在调用之前执行此操作:
await Dispatcher.Yield( DispatcherPriority.ApplicationIdle );
这使得事件循环可以在代码继续之前简要地接管并处理所有未完成的事件(包括文本和背景颜色更新)。
答案 1 :(得分:1)
我想整个代码都在GUI线程中运行,并阻止WPF更新GUI。
试试这个:
private async void OnTryP4Login(object sender, RoutedEventArgs e)
{
statusText.Text = string.Format("Connecting to {0} as '{1}'.",
textBoxUri.Text, textBoxUser.Text); // <-- Doesn't work
statusBar.Background = Brushes.Yellow; // <-- Doesn't work
await Task.Delay(100);
if (m_Manager.P4Login(textBoxUri.Text, textBoxUser.Text,
textBoxClientSpec.Text, passwordBox.Password))
{
statusText.Text = "SUCCESS!"; // <-- Doesn't work
statusBar.Background = Brushes.Green; // <-- Doesn't work
Thread.Sleep(2000);
this.Close();
}
else
{
statusBar.Background = Brushes.Red; // <-- THIS works
statusText.Text = "Error connecting to Perforce server!"; // <-- THIS works
buttonConnect.Visibility = Visibility.Collapsed;
buttonOK.Visibility = Visibility.Visible;
}
}
如果有效,你应该像那样运行实际的登录asyncron:
var loginSucceeded = await Task.Run(() => m_Manager.P4Login(textBoxUri.Text, textBoxUser.Text,
textBoxClientSpec.Text, passwordBox.Password));
而不是使用Task.Delay(100)
。