我的wpf程序中有多个选项卡,打开每个选项卡都会加载不同的UserControl。
在我的主窗口上,我有一些项目,如进度条和选项卡标题,它们应该在所有UserControls中都可见。下面是我的主窗口的样子
<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。堆栈面板具有文本框。在调用文本框的“text”的“Set”时,绑定的属性将检查文本并设置绑定到文本框的边框的“brush”属性。因此,用户可以实时查看它们是正确还是错误。
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。
发布于 2015-11-18 04:04:11
我认为对你来说最好的方法是创建一个Wizard。
发布于 2015-11-18 04:13:57
对于这样的东西,我会有一个如下所示的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;
}
}如果Next按钮必须位于Tab中的各个控件上,那么您可能会这样做
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; }就我个人而言,我不喜欢这样,但这是一个选择:)
https://stackoverflow.com/questions/33765611
复制相似问题