我的wpf程序中有多个选项卡,每个选项卡都会加载一个不同的UserControl。
在我的主窗口中,我有一些项目,例如进度条和标题页眉,这些项目应该在所有UserControl中都可见。这是我的主窗口的样子
<UserControl.DataContext>
<vm:ValuesCheck></vm:ValuesCheck>
</UserControl.DataContext>
<Grid>
<ProgressBar Height="20" Minimum="0" Maximum="7" Padding="30" Name="pb_status" Value="{Binding pb_Value}" />
</Grid>
<TabControl>
<TabItem Header="Introduction">
<!--Code for My intro tab-->
</TabItem>
<TabItem Header="Step 1">
<my:Step1 Loaded="Step1_Loaded" />
</TabItem>
<TabItem Header="Step 2" IsEnabled="{Binding step2Enabled}">
<my:Step2 Loaded="Step2_Loaded" />
</TabItem>
<TabItem Header="Step 3" IsEnabled="{Binding step3Enabled}">
<my:Step3 Loaded="Step3_Loaded" />
</TabItem>
</TabControl>
对于每个用户控件,我已将堆栈面板的数据上下文设置为每个用户控件的不同ViewModel。堆栈面板有文本框。致电&#39; Set&#39; &#39;文本&#39;在文本框中,bound属性检查文本并设置&#39; brush&#39;属性绑定到文本框的borderbrush。因此,用户可以实时查看它们是正确还是错误。
decimal _cAS;
public decimal cAS
{
get { return _cAS; }
set
{
_cAS = value;
OnPropertyChanged("cAS");
BrushConverter converter = new BrushConverter();
if (_cAS<= 17 || _cAS >= 19)
CASB= (Brush)converter.ConvertFromString("#FF0000");
else
CASB = (Brush)converter.ConvertFromString("#008000");
}
}
System.Windows.Media.Brush _casb;
public System.Windows.Media.Brush CASB
{
get { return _casb; }
set { _casb = value; OnPropertyChanged("CASB"); }
}
<TextBox Name="cAS" Text="{Binding cAS, UpdateSourceTrigger=PropertyChanged}"
BorderBrush="{Binding CASB, UpdateSourceTrigger=PropertyChanged}" ...>
现在我不知道如何继续。我想启用下一个选项卡,并在按下每个选项卡上的按钮时增加进度条。我在xaml背后的代码中这样做。
private void proceed3_Click(object sender, RoutedEventArgs e)
{
var vm = DataContext as ViewModel.ValuesCheck;
vm.step4Enabled = true;
}
我如何在后面的代码中知道正确输入了所有值。按钮的数据上下文是mainViewModel,而不是特定的ViewModel。
答案 0 :(得分:0)
我认为最适合您的方法是创建一个Wizard。
答案 1 :(得分:0)
对于这样的事情,我会看到类似这样的MainViewModel
public class MainViewModel
{
ObservableCollection<ITabViewModel> Tabs { get; set; }
int CurrentTabIndex { get; set; }
int MaxTabIndex { get; set; }
int Progress { get; set; }
ICommand NextTab { get; set; }
public MainViewModel()
{
Tabs = new ObservableCollection<ITabViewModel>();
Tabs.Add(new Introduction());
Tabs.Add(new Step1());
Tabs.Add(new Step2());
Tabs.Add(new Step3());
Progress = 0;
CurrentTabIndex = 0;
MaxTabIndex = 0;
}
}
NextTab
命令CanExecute
看起来像这样:
public bool NextTabCanExecute()
{
// verify all tabs are valid so far
for (int i = 0; i <= MaxTabIndex; i++)
{
if (Tabs[i].IsValid)
return false;
}
// can't hit Next if we're on last tab
if (CurrentTabIndex == Tabs.Count - 1)
return false;
return true;
}
虽然NextTab
命令可能看起来像这样
public void NextTab()
{
if (CurrentTabIndex == Tabs.Count - 1)
return; // on last tab already
CurrentTabIndex++;
// if user is on last enabled tab
if (CurrentTabIndex == MaxTabIndex)
{
MaxTabIndex++;
Progress += 100 / Tabs.Count;
}
}
如果下一个按钮必须位于选项卡内的各个控件上,那么您可能会执行类似
的操作foreach(ITabViewModel tab in Tabs)
{
tab.NextButtonCommand = this.NextTab;
}
可能需要检查或调整一些额外的案例,但这应该会给你一个大致的想法。
当然,您的XAML可能还需要进行修改以支持此功能。
作为替代方案,您可以替换
ObservableCollection<ITabViewModel> Tabs { get; set; }
使用特定对象,例如
IntroViewModel Intro { get; set; }
Step1ViewModel Step1 { get; set; }
Step2ViewModel Step2 { get; set; }
Step3ViewModel Step3 { get; set; }
bool IsStep1Enabled { get; set; }
bool IsStep2Enabled { get; set; }
bool IsStep3Enabled { get; set; }
并让您的MainViewModel分配代理人以确定应该启用什么或当您点击下一步时会发生什么
Intro.NextDelegate = this.GoToStep1;
Step1.NextDelegate = this.GoToStep2;
Step2.NextDelegate = this.GoToStep3;
Step1.IsValidChanged += delegate { IsStep2Enabled = Step1.IsValid; }
Step2.IsValidChanged += delegate { IsStep3Enabled = Step2.IsValid; }
就我个人而言,我不会这样,但这是一个选择:)