我创建了自定义窗口(标题栏,最小/最大/外部按钮,自己的窗口操作边框以及许多样式和触发器)。
定义了5种方法(我想覆盖):
从窗口标记:
SourceInitialized="Window_SourceInitialized"
Closing="Window_Closing"
从标题栏按钮:
Exit_Click()
Max_Click()
Min_Click()
最后我有DockPanel
<DockPanel Name="ClientArea"/>
我想把我的内容放在哪里
我尝试过添加代码中的内容:
BaseWindow editInterfaceWindow = new BaseWindow() { Owner = this };
editInterfaceWindow.DataContext = new EditInterface();
editInterfaceWindow.ShowDialog();
但是这样一些绑定停止工作并且在editInterfaceWindow里面我因为Owner = this
而无法以这种方式创建另一个窗口。构造函数中InitializeComponent()
也存在一些问题。
EditInterface UserControl <ListView Name="LBAvaliable" ItemsSource="{Binding AvaliableFaces, UpdateSourceTrigger=PropertyChanged}">
中的ListView在代码中不可见为LBAvaliable。
我几次使用该窗口,手动填写ClientArea内容。 我应该如何创建其他窗口,以便我可以继承它或只定义绑定?所以我的每个窗口的XAML都不需要大约1000行代码。
答案 0 :(得分:1)
过去我曾使用MVVMCross Framework而我们自己也不必为此担心。虽然这不是最好的,但这里有一个关于你能做什么的想法。
查看模型:预定义的3个按钮操作可供您设置/覆盖。
public class MainUCViewModel : ViewModelBase
{
private Action<object> btnACommand;
private Action<object> btnBCommand;
private Action<object> btnCCommand;
private object ccVM;
public ViewModelBase CCVM
{
get { return this.ccVM; }
set
{
this.ccVM = value;
OnPropertyChanged(); // Notify View
}
}
public MainUCViewModel()
{
}
public RelayCommand BtnACommand
{
get { return new RelayCommand(btnACommand); }
}
public RelayCommand BtnBCommand
{
get { return new RelayCommand(btnBCommand); }
}
public RelayCommand BtnCCommand
{
get { return new RelayCommand(btnCCommand); }
}
public void SetBtnACommand(Action<object> action)
{
this.btnACommand = action;
}
public void SetBtnBCommand(Action<object> action)
{
this.btnBCommand = action;
}
public void SetBtnCCommand(Action<object> action)
{
this.btnCCommand = action;
}
}
查看:
<UserControl x:Class="WpfApplication1.Views.UserControls.MainUC"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="750">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="45" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<StackPanel Orientation="Horizontal">
<Button Command="{Binding BtnACommand}" Width="100">
<TextBlock>A</TextBlock>
</Button>
<Rectangle Width="15" />
<Button Command="{Binding BtnBCommand}" Width="100">
<TextBlock>B</TextBlock>
</Button>
<Rectangle Width="15" />
<Button Command="{Binding BtnCCommand}" Width="100">
<TextBlock>C</TextBlock>
</Button>
</StackPanel>
</Grid>
<Grid Grid.Row="1">
<ContentControl x:Name="CCMain" Content="{Binding CCVM}"/>
</Grid>
</Grid>
</UserControl>
看看Thinking with MVVM: Data Templates + ContentControl。只需为视图模型定义数据模板即可。
<Window.Resources>
<DataTemplate DataType="{x:Type ViewModel:GeneralSettingsViewModel}">
<View:GeneralSettingsView/>
</DataTemplate
<DataTemplate DataType="{x:Type ViewModel:AdvancedSettingsViewModel}">
<View:AdvancedSettingsView/>
</DataTemplate>
</Window.Resources>
我在这里说的是GeneralSettingsViewModel应该是 使用GeneralSettingsView呈现。这正是我们所需要的! 因为视图是使用DataTemplate创建的,所以我们不需要 设置DataContext,它会自动注册到 模板化对象,ViewModel。
答案 1 :(得分:0)
您的问题有两种主要方法:
对于方法1,设计窗口并使方法可重写:
在基本窗口xaml中,分配处理程序和所需的一切:
<Window x:Class="WpfTests.MainWindow"
...
SourceInitialized="Window_SourceInitialized">
在基本窗口中,将处理程序定义为protected virtual
(或abstract
,如果您想强制执行它们的话)
public partial class MainWindow : Window
{
// ...
protected virtual void Window_SourceInitialized(object sender, EventArgs e)
{
}
// ...
}
创建派生窗口
public class ExWindow : MainWindow
{
protected override void Window_SourceInitialized(object sender, EventArgs e)
{
// specialized code here
}
}
将App.xaml更改为使用Startup
而不是StartupUri
<Application x:Class="WpfTests.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup">
手动创建第一个窗口,选择一个继承的窗口类
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
var window = new ExWindow();
window.Show();
}
}
第二种方法 - 可配置窗口 - 遵循与良好用户控件设计相同的原则:窗口/控件属性由创建者控制,而不是由窗口/控件本身控制。
因此,不要在窗口代码中定义一些事件处理程序,只需将此练习留给用户,用户希望知道窗口应该做什么:
public partial class MainWindow : Window
{
// I don't care for SourceInitialized (also remove it from XAML)
}
在App.xaml中或创建窗口的任何地方:
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
var window = new MainWindow();
window.SourceInitialized += window_SourceInitialized;
window.Show();
}
void window_SourceInitialized(object sender, EventArgs e)
{
var window = sender as MainWindow;
// I know how to handle this event for this window instance
}
}