我一直在寻找解决方案的时间。 我有一个选项卡适配器类,我用来填充选项卡控件
public partial class TabAdapter : UserControl
{
public static readonly DependencyProperty fileNameProperty =
DependencyProperty.Register(
"fileName",
typeof(string),
typeof(TabAdapter),
new FrameworkPropertyMetadata(
string.Empty,
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnFileNamePropertyChanged),
new CoerceValueCallback(coerceFileName)
),
new ValidateValueCallback(fileNameValidationCallback)
);
public TabAdapter()
{
InitializeComponent();
//initializeInterior();
CreateSaveCommand();
TabAdapterContent.DataContext = this;
Console.WriteLine("constructor hit.");
}
public string fileName
{
get { return (string)GetValue(fileNameProperty); }
set { SetValue(fileNameProperty, value); }
}
private ColumnMapper _columnMap;
private TableMapper _tableMap;
private TabType tabType;
private enum TabType { TABLE_MAPPER, COLUMN_MAPPER, ERROR_MSG }
private static object coerceFileName(DependencyObject d, object value)
{
return fileName;
}
private static bool fileNameValidationCallback(object Value)
{
string fn = (string)Value;
if (fn.Equals(string.Empty))
{
return true;
}
FileInfo fi = new FileInfo(fn);
return ((fi.Exists && fi.Extension.Equals(".csv")));
}
private static void OnFileNamePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
{
TabAdapter source = d as TabAdapter;
Console.WriteLine("got to property changer: " + (string)args.NewValue + " :new / old: " + (string)args.OldValue);
source.initializeInterior();
}
private void initializeInterior()
{
Console.WriteLine("initializing Interior filename: " + fileName);
if (Regex.IsMatch(fileName, @".*_SourceTableMapping.csv$"))
{
tabType = TabType.TABLE_MAPPER;
_tableMap = new TableMapper(fileName);
Grid.SetRow(_tableMap, 0);
Grid.SetColumn(_tableMap, 0);
//clear out the content.
this.TabAdapterContent.Children.Clear();
//add new content
this.TabAdapterContent.Children.Add(_tableMap);
}
else if (fileName.EndsWith(".csv"))
{
tabType = TabType.TABLE_MAPPER;
_columnMap = new ColumnMapper(fileName);
Grid.SetRow(_columnMap, 0);
Grid.SetColumn(_columnMap, 0);
//clear out the content.
this.TabAdapterContent.Children.Clear();
//add new content
this.TabAdapterContent.Children.Add(_columnMap);
}
else
{
tabType = TabType.ERROR_MSG;
TextBlock tb = new TextBlock();
tb.Text = "The File: " + fileName + " is not a valid mapping file.";
Grid.SetRow(tb, 0);
Grid.SetColumn(tb, 0);
//clear out the content.
this.TabAdapterContent.Children.Clear();
//add new content
this.TabAdapterContent.Children.Add(tb);
}
}
}
重点是决定添加什么类型的文件,并在其中加载正确的用户控件以显示该文件。
标签控件的主窗口xaml是
<TabControl x:Name="tabControl" Grid.Column="1" Grid.Row="0" ItemsSource="{Binding openFileNames, Mode=OneWay}">
<TabControl.LayoutTransform>
<!-- Allows to zoom the control's content using the slider -->
<ScaleTransform CenterX="0"
CenterY="0" />
<!-- part of scale transform ScaleX="{Binding ElementName=uiScaleSlider,Path=Value}"
ScaleY="{Binding ElementName=uiScaleSlider,Path=Value}" />-->
</TabControl.LayoutTransform>
<!-- Header -->
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header}" />
</DataTemplate>
</TabControl.ItemTemplate>
<!-- Content -->
<TabControl.ContentTemplate>
<DataTemplate>
<local:TabAdapter fileName="{Binding fileName}" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
标题有效,如果我改变了
<local:TabAdapter fileName="{Binding fileName}" />
进入
<TextBlock Text="{Binding fileName}" />
然后它都正确绑定,我感觉它与我的选项卡适配器上的数据上下文有关。但不完全确定需要设置的内容。
我的选项卡适配器的xaml是
<UserControl x:Class="ImportMappingGui.TabAdapter"
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="300" d:DesignWidth="300">
<Grid x:Name="TabAdapterContent">
<Grid.RowDefinitions>
<RowDefinition Height = "*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
</Grid>
它将全部编译并运行,但只有用户控件的构造函数被命中,并且只有一次,无论我创建多少个选项卡。 这是我的第一个WPF应用程序,所以我很抱歉,如果它是一个愚蠢的我缺少。 (或者,如果我设置各种适配器的方法不是解决此问题的最佳方法)。
答案 0 :(得分:0)
不要在UserControl本身内设置DataContext
的{{1}}。它打败了“无望”的全部观点。可以用来显示你传递的任何内容的控件。
您的UserControl
绑定失败,因为fileName
和DataContext = this
是this
控件本身,而TabAdapter
实际上并未设置为任何内容。 (请记住,绑定告诉属性在其他地方检索它的值与直接设置值不同)
对于没有运行多次的构造函数,这是设计的。由于您告诉TabControl使用TabAdapter.fileName
控件作为模板,因此它将创建TabAdapter
的一个副本,并在切换选项卡时简单地替换控件后面的TabAdapter
。这样可以提高性能,因为它不必为每个选项卡保持初始化和跟踪单独的控件,并减少使用的内存。