尝试从用户控件更改主 window 的 DataContext
Trying to change DataContext of main window from usercontrol
在初始化 main window 时,我将 DataContext 设置为用户控件,在此用户控件上我有一个事件,假设将 main window 的数据上下文更改为另一个用户控件,但没有任何反应。
这里是主要的 window 的 xaml:
</Window.Resources>
<Grid>
<ContentControl Content="{Binding}" Width="auto" Height="auto" />
</Grid>
这是主要的 C# window:
public MainWindow()
{
InitializeComponent();
DataContext = new LogInViewModel();
}
这是 LogInUserControl 的 xaml:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Grid.Column="1" Grid.Row="1">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Width="250">
<StackPanel Width="125">
<TextBlock Text="Email:" Margin="5,0,5,0" Width="auto"/>
</StackPanel>
<StackPanel Width="125">
<TextBlock Text="Password:" Margin="5,0,0,0" Width="auto"/>
</StackPanel>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBox Margin="5,0,5,0" HorizontalAlignment="Center" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<PasswordBox Margin="0,0,0,5" HorizontalAlignment="Center" Height="23" VerticalAlignment="Top" Width="120"/>
</StackPanel>
<Button Content="Log In" Margin="0,0,0,5" HorizontalAlignment="Center" VerticalAlignment="Top" Width="75"/>
</StackPanel>
<Grid Grid.Column="1" Grid.Row="1">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="don't have account yet ?" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="5"/>
<TextBlock Name="TBSignUp" Text="Sign Up" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="5" PreviewMouseLeftButtonDown="TextBlock_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="TextBlock_PreviewMouseLeftButtonUp" Foreground="#FF0B36F5"/>
</StackPanel>
</Grid>
</Grid>
这是用于 LogInUserControl 的 C#:
public partial class LogInView : UserControl
{
string BlackForeground = "#FF000000" ;
string OriginalForeground = "#FF0B36F5";
public LogInView()
{
InitializeComponent();
}
private void TextBlock_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
TBSignUp.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString(OriginalForeground));
DataContext = new RegisterView();
}
private void TextBlock_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
TBSignUp.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString(BlackForeground));
}
}
您需要在 App.xaml.cs
上设置它。
App.xaml.cs:
public class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
MainWindow window=new MainWindow();
LogInViewModel vm=new LogInViewModel(); // You need to set DataContext...
window.DataContext=vm; // ...before showing up the window.
window.Show();
}
}
在我通过研究发现的 ViewModel 模式中,用法是在 DataContext
之前,在 Show();
之后。
希望能解决您的问题。
在 WPF 中,您可以从任何地方获得 shell(第一个)window:
System.Windows.Window shell = System.Windows.Application.Current.MainWindow;
或
Application.Current.Windows[0];
但我建议在需要时传递引用。
查看 MVVM 模式,您需要在视图模型中实现 属性 更改通知 class 以绑定属性。
在初始化 main window 时,我将 DataContext 设置为用户控件,在此用户控件上我有一个事件,假设将 main window 的数据上下文更改为另一个用户控件,但没有任何反应。
这里是主要的 window 的 xaml:
</Window.Resources>
<Grid>
<ContentControl Content="{Binding}" Width="auto" Height="auto" />
</Grid>
这是主要的 C# window:
public MainWindow()
{
InitializeComponent();
DataContext = new LogInViewModel();
}
这是 LogInUserControl 的 xaml:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Grid.Column="1" Grid.Row="1">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Width="250">
<StackPanel Width="125">
<TextBlock Text="Email:" Margin="5,0,5,0" Width="auto"/>
</StackPanel>
<StackPanel Width="125">
<TextBlock Text="Password:" Margin="5,0,0,0" Width="auto"/>
</StackPanel>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBox Margin="5,0,5,0" HorizontalAlignment="Center" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<PasswordBox Margin="0,0,0,5" HorizontalAlignment="Center" Height="23" VerticalAlignment="Top" Width="120"/>
</StackPanel>
<Button Content="Log In" Margin="0,0,0,5" HorizontalAlignment="Center" VerticalAlignment="Top" Width="75"/>
</StackPanel>
<Grid Grid.Column="1" Grid.Row="1">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="don't have account yet ?" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="5"/>
<TextBlock Name="TBSignUp" Text="Sign Up" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="5" PreviewMouseLeftButtonDown="TextBlock_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="TextBlock_PreviewMouseLeftButtonUp" Foreground="#FF0B36F5"/>
</StackPanel>
</Grid>
</Grid>
这是用于 LogInUserControl 的 C#:
public partial class LogInView : UserControl
{
string BlackForeground = "#FF000000" ;
string OriginalForeground = "#FF0B36F5";
public LogInView()
{
InitializeComponent();
}
private void TextBlock_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
TBSignUp.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString(OriginalForeground));
DataContext = new RegisterView();
}
private void TextBlock_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
TBSignUp.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString(BlackForeground));
}
}
您需要在 App.xaml.cs
上设置它。
App.xaml.cs:
public class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
MainWindow window=new MainWindow();
LogInViewModel vm=new LogInViewModel(); // You need to set DataContext...
window.DataContext=vm; // ...before showing up the window.
window.Show();
}
}
在我通过研究发现的 ViewModel 模式中,用法是在 DataContext
之前,在 Show();
之后。
希望能解决您的问题。
在 WPF 中,您可以从任何地方获得 shell(第一个)window:
System.Windows.Window shell = System.Windows.Application.Current.MainWindow;
或
Application.Current.Windows[0];
但我建议在需要时传递引用。
查看 MVVM 模式,您需要在视图模型中实现 属性 更改通知 class 以绑定属性。