Вот вам решение VBA (я не знаю, как это сделать с помощью Python).
Если вам нужно преобразовать несколько файлов Word в другие форматы, такие как TXT, RTF, HTML или PDF, запустите приведенный ниже скрипт.
Option Explicit On
Sub ChangeDocsToTxtOrRTFOrHTML()
'with export to PDF in Word 2007
Dim fs As Object
Dim oFolder As Object
Dim tFolder As Object
Dim oFile As Object
Dim strDocName As String
Dim intPos As Integer
Dim locFolder As String
Dim fileType As String
On Error Resume Next
locFolder = InputBox("Enter the folder path to DOCs", "File Conversion", "C:\Users\your_path_here\")
Select Case Application.Version
Case Is < 12
Do
fileType = UCase(InputBox("Change DOC to TXT, RTF, HTML", "File Conversion", "TXT"))
Loop Until (fileType = "TXT" Or fileType = "RTF" Or fileType = "HTML")
Case Is >= 12
Do
fileType = UCase(InputBox("Change DOC to TXT, RTF, HTML or PDF(2007+ only)", "File Conversion", "TXT"))
Loop Until (fileType = "TXT" Or fileType = "RTF" Or fileType = "HTML" Or fileType = "PDF")
End Select
Application.ScreenUpdating = False
Set fs = CreateObject("Scripting.FileSystemObject")
Set oFolder = fs.GetFolder(locFolder)
Set tFolder = fs.CreateFolder(locFolder & "Converted")
Set tFolder = fs.GetFolder(locFolder & "Converted")
For Each oFile In oFolder.Files
Dim d As Document
Set d = Application.Documents.Open(oFile.Path)
strDocName = ActiveDocument.Name
intPos = InStrRev(strDocName, ".")
strDocName = Left(strDocName, intPos - 1)
ChangeFileOpenDirectory tFolder
Select Case fileType
Case Is = "TXT"
strDocName = strDocName & ".txt"
ActiveDocument.SaveAs FileName:=strDocName, FileFormat:=wdFormatText
Case Is = "RTF"
strDocName = strDocName & ".rtf"
ActiveDocument.SaveAs FileName:=strDocName, FileFormat:=wdFormatRTF
Case Is = "HTML"
strDocName = strDocName & ".html"
ActiveDocument.SaveAs FileName:=strDocName, FileFormat:=wdFormatFilteredHTML
Case Is = "PDF"
strDocName = strDocName & ".pdf"
ActiveDocument.ExportAsFixedFormat OutputFileName:=strDocName, ExportFormat:=wdExportFormatPDF
End Select
d.Close
ChangeFileOpenDirectory oFolder
Next oFile
Application.ScreenUpdating = True
End Sub
I'm not exactly sure what your model looks like, but you can always use a . to bind to an objects property. For example:
<DataTemplate DataType="TerrainModels:Square">
<StackPanel>
<TextBlock Content="{Binding Path=Feature.Name}"/>
<TextBlock Content="{Binding Path=Feature.Type}"/>
</StackPanel>
</DataTemplate>
Update
Although, if you are looking for a way to bind two different objects in a collection you might want to take a look at the ItemTemplateSelector
property.
In your scenario it would be something like this (not tested):
public class TerrainSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var square = item as Square;
if (square == null)
return null;
if (square.Terrain is Dirt)
{
return Application.Resources["DirtTemplate"] as DataTemplate;
}
if (square.Terrain is Steel)
{
return Application.Resources["SteelTemplate"] as DataTemplate;
}
return null;
}
}
Then to use it you would have:
App.xaml
<Application ..>
<Application.Resources>
<DataTemplate x:Key="DirtTemplate">
<!-- template here -->
</DataTemplate>
<DataTemplate x:Key="SteelTemplate">
<!-- template here -->
</DataTemplate>
</Application.Resources>
</Application>
Window.xaml
<Window ..>
<Window.Resources>
<local:TerrainSelector x:Key="templateSelector" />
</Window.Resources>
<ItemsControl ItemSource="{Binding Path=Terrain}" ItemTemplateSelector="{StaticResource templateSelector}" />
</Window>
I'm adding another answer, because this is kind of a different take on the problem then my other answer.
If you are trying to change the background of the Canvas, then you can use a DataTrigger like this:
<DataTemplate DataType="{x:Type WpfApplication1:Square}">
<DataTemplate.Resources>
<WpfApplication1:TypeOfConverter x:Key="typeOfConverter" />
</DataTemplate.Resources>
<Canvas Name="background" Fill="Green" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path="Terrain" Converter={StaticResource typeOfConverter}}" Value="{x:Type WpfApplication1:Dirt}">
<Setter TargetName="background"Property="Fill" Value="Tan" />
</DataTrigger>
<DataTrigger Binding="{Binding Path="Terrain" Converter={StaticResource typeOfConverter}}" Value="{x:Type WpfApplication1:SteelPlate}">
<Setter TargetName="background" Property="Fill" Value="Silver" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
You'd also need to use this Converter:
public class TypeOfConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value.GetType();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
Я полагаю, что лучшее, что вы можете сделать для устранения накладных расходов (и избыточности) визуального дерева, это:
<ItemsControl ItemsSource="{Binding Squares}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Terrain}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Я мог бы поклясться, что вы могли бы сделать этот шаг дальше, непосредственно назначив ] Свойство Content
объекта ContentPresenter
, сгенерированного для каждого элемента в ItemsControl
:
<ItemsControl ItemsSource="{Binding Squares}">
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="ContentPresenter.Content" Content="{Binding Terrain}"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
Однако, у ContentPresenter
, похоже, есть родительский элемент DataContext
как его DataContext
, а не как квадрат
. Это не имеет смысла для меня. Он отлично работает с ListBox
или любым другим ItemsControl
подклассом. Возможно, это ошибка WPF - не уверен. Я должен буду изучить это далее.