我有一个带TabControl的WPF应用程序和几个包含一个UserControl的TabItem。用户可以更改TabItem中包含的usercontrol中的条目,例如配置应用程序。
<TabControl>
<TabItem Header="Configuration">
<views:ConfigurationView x:Name="ConfigurationView_Object" />
</TabItem>
<TabItem Header="Artist">
...
</TabItem>
</TabControl>
我有一个函数可以检查UserControl中是否有未保存的更改。 在用户更改标签或关闭应用程序之前,我想让他选择保存,放弃或留在标签页上。
这可能吗?如果可以,怎么样?如果它需要一些除TabControl之外的其他控件/结构,那么它们也会起作用,因为我目前正处于规划阶段......
提前致谢,
弗兰克
答案 0 :(得分:0)
您可以将交互性用于任何事件。这是MVVM解决方案。
<TabControl>
<TabItem Header="Configuration">
<views:ConfigurationView x:Name="ConfigurationView_Object" />
<intr:Interaction.Triggers>
<intr:EventTrigger EventName="MouseUp">
<intr:InvokeCommandAction Command="{Binding Yourcommand}" CommandParameter="YourCommandParameter"/>
</intr:EventTrigger>
</intr:Interaction.Triggers>
答案 1 :(得分:0)
如果要通过事件执行此操作,可以使用SelectionConhanged事件作为TabControl,使用Closing事件作为Window。像这样:
XAML:
<Window x:Class="Namespace.View"
.....
Closing="Window_Closing">
......
C#:
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (UnsavedChanges())
{
//save changes
}
}
XAML:
<TabControl SelectionChanged="TabControl_SelectionChanged">
<TabItem Header="Configuration">
<views:ConfigurationView x:Name="ConfigurationView_Object" />
</TabItem>
<TabItem Header="Artist">
...
</TabItem>
</TabControl>
C#:
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (UnsavedChanges())
{
//save changes
}
}
答案 2 :(得分:0)
TabControl没有TabChanging事件。但是,您可以使用.Items.CurrentChanging
事件。这仅适用于在TabControl
IsSynchronizedWithCurrentItem="True"
的情况
XAML **
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height='1*' />
<RowDefinition Height='Auto' />
</Grid.RowDefinitions>
<TabControl x:Name='MainTab'
IsSynchronizedWithCurrentItem='True'
Grid.Row='0'>
<TabItem x:Name='TabTickets'
Header='Tickets'>
<StackPanel Orientation='Horizontal' >
<TextBlock Text='Provide some text:'
Margin='10,0' />
<TextBox x:Name='ExampleTextBox'
VerticalAlignment='Top' MinWidth='90' />
</StackPanel>
</TabItem>
<TabItem x:Name='TabCalendar'
Header='Calendar' />
<TabItem x:Name='TabAbout'
Header='About' />
</TabControl>
<TextBlock x:Name='MessageTextBox'
Grid.Row='1' />
</Grid>
<强>代码强>
public TabChangingWindow() {
InitializeComponent();
MainTab.Items.CurrentChanging += Items_CurrentChanging;
}
void Items_CurrentChanging(object sender,
System.ComponentModel.CurrentChangingEventArgs e) {
if (e.IsCancelable)
{
var fromElement = ((ICollectionView)sender).CurrentItem as FrameworkElement;
var toElement = MainTab.SelectedItem as FrameworkElement;
if (fromElement!= null && toElement!= null)
{
if (ExampleTextBox.Text.Length == 0)
{
e.Cancel = true;
MessageTextBox.Text = "Example Text cannot be blank.";
MainTab.SelectedItem = fromElement;
}
else
{
MessageTextBox.Text =
String.Format("Changing from {0} to {1}", fromElement.Name, toElement.Name);
}
}
}
}
<强>截图强>
当数据不完整时,阻止移动到另一个标签页。
数据完成后,允许移至另一个标签页。
答案 3 :(得分:0)
我终于自己实现了一个简单的tabcontrol,因为那时我可以控制一切。
<WrapPanel x:Name="WrapPanel_Main"> <!-- This is the TabControl -->
<Border x:Name="Border_Configuration" Margin="5,5,0,0" BorderThickness="4,4,4,0"> <!-- This is the first tab -->
<TextBlock x:Name="TextBlock_Configuration" Text="Configuration" Padding="5" MouseLeftButtonUp="TextBlock_Step_MouseLeftButtonUp"/>
</Border>
<Border Margin="5,5,0,0" BorderThickness="4,4,4,0"> <!-- This is the second tab -->
<TextBlock x:Name="TextBlock_Artists" Text="Artists" Padding="5" MouseLeftButtonUp="TextBlock_Step_MouseLeftButtonUp" />
</Border>
<Border Margin="5,5,0,0" BorderThickness="4,4,4,0"> <!-- This is the third tab -->
<TextBlock x:Name="TextBlock_ReleaseGroups" Text="Release Groups" Padding="5" MouseLeftButtonUp="TextBlock_Step_MouseLeftButtonUp"/>
</Border>
</WrapPanel>
<Border x:Name="Border_Placeholder" Grid.Row="1" Margin="5,0,5,5"> <!-- placeholder for the content of each tab -->
<ContentControl x:Name="ContentControl_Placeholder" Grid.Row="1" Padding="5" />
</Border>
这里是处理&#34; Tabs&#34;的Mouse-Up-Event的处理程序。我创建了一个接口,每个用作控件的内容都必须实现。这允许用户控制通知&#34; Tab Control&#34;关于未保存的更改并采取适当的(用户选择)操作。 之后,它会加载新内容并更改&#34; Tab-Headers&#34;的外观。在我看来,对于标签更改的完全控制,这导致更多代码的数量是可以接受的。
private void TextBlock_Step_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
ICancelUnloading currentElement = ContentControl_Placeholder.Content as ICancelUnloading;
if (currentElement != null)
{
if (currentElement.UnsavedChanges)
{
MessageBoxResult result = MessageBox.Show("Yes: Save, No: Discard, Cancel: Stay", "Unsaved Changes", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (result == MessageBoxResult.Cancel)
return;
if (result == MessageBoxResult.Yes)
currentElement.Save();
}
}
TextBlock textBlock = sender as TextBlock;
if (textBlock != null)
{
switch (textBlock.Name)
{
case "TextBlock_Configuration":
ContentControl_Placeholder.Content = new ConfigurationView();
break;
case "TextBlock_Artists":
ContentControl_Placeholder.Content = new ArtistsView();
break;
case "TextBlock_ReleaseGroups":
ContentControl_Placeholder.Content = new ReleaseGroupsView();
break;
}
ActivateTab(textBlock);
}
}