Reuse element defined further up in App.xaml - wpf

I declare several converters in my App.xaml as follows but I am repeating myself which I really would like to avoid:
<c:ConverterChain x:Key="IsNotNull">
<c:IsNullConverter />
<c:InvertBoolConverter />
</c:ConverterChain>
<c:ConverterChain x:Key="HideWhenNull">
<c:IsNullConverter />
<c:InvertBoolConverter />
<c:BoolToFromVisibilityConverter FalseEquivalent="Hidden" />
</c:ConverterChain>
<c:ConverterChain x:Key="CollapseWhenNull">
<c:IsNullConverter />
<c:InvertBoolConverter />
<c:BoolToFromVisibilityConverter FalseEquivalent="Collapsed" />
</c:ConverterChain>
As you can see the IsNotNull could be reused in the two following converter chains, but is it possible to declare that somehow? I'm thinking of something like:
<c:ConverterChain x:Key="HideWhenNull">
<Reference Name="IsNotNull" />
<c:BoolToFromVisibilityConverter FalseEquivalent="Hidden" />
</c:ConverterChain>
Is there some WPF concept out there to cover this use case?

<c:ConverterChain x:Key="HideWhenNull">
<DynamicResource ResourceKey="IsNotNull"/>
<c:BoolToFromVisibilityConverter FalseEquivalent="Hidden" />
</c:ConverterChain>
As long as the ConverterChain class supports nesting.

Inspired by Khyads answer I opted for StaticResource instead of DynamicResource because there is no need for the extra overhead Dynamic implies and it works just fine with a static resource:
<c:ConverterChain x:Key="HideWhenNull">
<StaticResource ResourceKey="IsNotNull" />
<c:BoolToFromVisibilityConverter FalseEquivalent="Hidden" />
</c:ConverterChain>

Related

What is Contoso and can i replace it for another thing?

I'm developing an addin for excel and I want to know What is Contoso and if i can replace it for another thing.
In my manifest file i have this:
<Label resid="Contoso.TaskpaneButton.Label" />
<Supertip>
<!-- ToolTip title. resid must point to a ShortString resource. -->
<Title resid="Contoso.TaskpaneButton.Label" />
<!-- ToolTip description. resid must point to a LongString resource. -->
<Description resid="Contoso.TaskpaneButton.Tooltip" />
</Supertip>
<Icon>
<bt:Image size="16" resid="Contoso.tpicon_16x16" />
<bt:Image size="32" resid="Contoso.tpicon_32x32" />
<bt:Image size="80" resid="Contoso.tpicon_80x80" />
</Icon>
For example, can i replace <Label resid="Contoso.TaskpaneButton.Label" /> to <Label resid="Anything.TaskpaneButton.Label" />

Xceed themes override all other styles

I'm using an xceed datagrid with the Office2007BlackTheme. I also have a lot of styles, that I want to apply to UI controls inside my datagrid. Unfortunately the theme seems to override everything as long as its inside the datagrid.
It is worth noting that datagrid-related styles like "ColumnManagerCell" or "DataRow" still work as expected.
For example: I want to use my own style for the scrollbars, but even though the style is set to be applied globally; <Style TargetType="{x:Type ScrollBar}">, it is still overridden in the datagrid. Outside of the grid it is not.
I realize that this is because, by default, the theme is set implicitly, but there doesn't seem to be anyway of setting it explicitly.
Is there a way to explicitly set the ScrollBar style (& others) after applying the theme? Maybe there's a way to base the tableflowview on the theme so it doesn't override other styles? I've looked around and did not find any solution.
I'm using Xceed DataGrid for WPF 6.3 with ThemePack 1-5. (Only DataGrid: xceed.com/xceed-datagrid-for-wpf paid version)
Any help is appreciated.
Here's my code for the DataGrid:
<xcdg:DataGridControl x:Name="datagrid"
ItemsSource="{Binding Source={StaticResource Features}}"
KeyUp="DatagridKeyUp"
AllowDetailToggle="True"
Margin="10"
NavigationBehavior="RowOrCell"
CellEditorDisplayConditions="RowIsBeingEdited,
MouseOverCell, MouseOverRow, RowIsCurrent, CellIsCurrent"
EditTriggers="BeginEditCommand, ClickOnCurrentCell,
SingleClick, CellIsCurrent, ActivationGesture, RowIsCurrent"
ItemScrollingBehavior="Immediate"
AutoCreateColumns="False">
<xcdg:DataGridControl.View>
<xcdg:TableflowView>
<!--Remove ugly header-->
<xcdg:TableflowView.FixedHeaders>
<DataTemplate>
<xcdg:ColumnManagerRow />
</DataTemplate>
</xcdg:TableflowView.FixedHeaders>
<!-- THEME IS SET HERE! -->
<xcdg:TableflowView.Theme>
<xcdg:Office2007BlackTheme/>
</xcdg:TableflowView.Theme>
</xcdg:TableflowView>
</xcdg:DataGridControl.View>
<xcdg:DataGridControl.Resources>
<Style TargetType="xcdg:TableViewScrollViewer">
<Setter Property="HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="VerticalScrollBarVisibility" Value="Auto" />
</Style>
</xcdg:DataGridControl.Resources>
<xcdg:DataGridControl.Columns>
<xcdg:Column FieldName="FeatureID" Title="FeatureID" ReadOnly="True"/>
<xcdg:Column FieldName="Name" Title="Feature name" ReadOnly="True" />
<xcdg:Column FieldName="Description" Title="Description" ReadOnly="True" />
<xcdg:UnboundColumn FieldName=" " />
</xcdg:DataGridControl.Columns>
<xcdg:DataGridControl.DetailConfigurations>
<xcdg:DetailConfiguration RelationName="Settings" UseDefaultHeadersFooters="False">
<xcdg:DetailConfiguration.Headers>
<DataTemplate>
<xcdg:ColumnManagerRow />
</DataTemplate>
</xcdg:DetailConfiguration.Headers>
<xcdg:DetailConfiguration.Columns>
<xcdg:Column FieldName="Name" Title="Name" ReadOnly="True" />
<xcdg:Column FieldName="Description" Title="Description" ReadOnly="True" />
<xcdg:Column FieldName="EditValues" Title="Edit Values" ReadOnly="True" />
<xcdg:Column FieldName="EditValueVar" Title="Edit Value" Width="150" ReadOnly="False"
CellContentTemplateSelector="{StaticResource SettingsDataTemplateSelector}"
DisplayMemberBinding="{Binding}" />
<xcdg:UnboundColumn FieldName=" " />
</xcdg:DetailConfiguration.Columns>
</xcdg:DetailConfiguration>
</xcdg:DataGridControl.DetailConfigurations>
</xcdg:DataGridControl>

WPF WindowsFormsHost control is not woking showing error

I am using WindowsFormsHost to show DataGridView in my WPF application.
<wfi:WindowsFormsHost Name="winhost" Grid.Row="0" Width="930" Height="200" Margin="5,5,5,0" Visibility="Hidden">
<wf:DataGridView x:Name="dataGridViewOutlookMailList" ScrollBars="Both" AllowUserToAddRows="False" RowHeadersVisible="False" CellContentClick="dataGridViewOutlookMailList_CellContentClick">
<wf:DataGridView.Columns>
<wf:DataGridViewCheckBoxColumn Name="dataGridViewCheckBoxColumn3" HeaderText="" Width="25" Visible="True" />
<wf:DataGridViewTextBoxColumn Name="dataGridViewTextBoxColumn13" HeaderText="Outlook Entry ID" Width="100" Visible="false" />
<wf:DataGridViewTextBoxColumn Name="dataGridViewTextBoxColumn14" HeaderText="FullPath With FileName" Width="100" Visible="False" />
<wf:DataGridViewTextBoxColumn Name="dataGridViewTextBoxColumn15" HeaderText="Resume Name" Width="100" Visible="True" />
<wf:DataGridViewTextBoxColumn Name="dataGridViewTextBoxColumn18" HeaderText="Sender Name" Width="100" Visible="True" />
<wf:DataGridViewTextBoxColumn Name="dataGridViewTextBoxColumn17" HeaderText="Received By Name" Width="100" Visible="True" />
<wf:DataGridViewTextBoxColumn Name="dataGridViewTextBoxColumn16" HeaderText="Received" Width="100" Visible="True" />
<wf:DataGridViewTextBoxColumn Name="dataGridViewTextBoxColumn19" HeaderText="Sender Address" Width="100" Visible="True" />
<wf:DataGridViewTextBoxColumn Name="dataGridViewTextBoxColumn20" HeaderText="To" Width="100" Visible="True" />
<wf:DataGridViewTextBoxColumn Name="dataGridViewTextBoxColumn21" HeaderText="Bcc" Width="100" Visible="True" />
<wf:DataGridViewTextBoxColumn Name="dataGridViewTextBoxColumn22" HeaderText="Cc" Width="100" Visible="True" />
<wf:DataGridViewTextBoxColumn Name="dataGridViewTextBoxColumn23" HeaderText="Subject" Width="100" Visible="True" />
<wf:DataGridViewTextBoxColumn Name="dataGridViewTextBoxColumn24" HeaderText="Body" Width="100" Visible="True" />
<wf:DataGridViewCheckBoxColumn Name="dataGridViewCheckBoxColumn4" HeaderText="NotesActivity" Width="25" Visible="False" />
<wf:DataGridViewCheckBoxColumn Name="dataGridViewCheckBoxColumn5" HeaderText="Body As Attachment" Width="100" Visible="False" />
</wf:DataGridView.Columns>
</wf:DataGridView>
I am getting following error while mouse over on datagridview also the UI is not loaded properly. see the screen shot for details.
I am also using following code
WinForms.DataGridViewCellStyle ColStyle1 = new WinForms.DataGridViewCellStyle();
System.Drawing.Text.PrivateFontCollection pfc = new System.Drawing.Text.PrivateFontCollection();
pfc.AddFontFile(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + #"\NewZrr\OpenSans-Regular.ttf");
foreach (WinForms.DataGridViewColumn c in dataGridViewOutlookMailList.Columns)
{
c.DefaultCellStyle.Font = new System.Drawing.Font(pfc.Families[0], 8, System.Drawing.FontStyle.Regular);
}
pfc = null;
in my Window_Loaded method to change the font of datagridview. kindly guide me to resolve the issue.
The problem is that the PrivateFontCollection instance in the pfc variable goes out of scope, so when the DataGridViewCell is drawn for the first time the specified font cannot be loaded correctly.
Move the pfc instance outside the Window_Loaded method to prevent GC from collecting it, and do not set it to null, make it a long-living object.
Reference: Parameter is not valid when draw text in label with custom font

Need to use an inner data Template that is the same as outer template

I have the following XML structure(simplified for example's sake) where you can have questions within questions. There are other types of questions so I have decided to make a template to display them, I can create the top level of questions show, but when i get to the inner levels I can't get my template to show. I do have other question types other than "string", but I removed them to try to focus on the issue at hand.
The XML structure
<QUESTIONS>
<QUESTION id="3" text="What is this?" type="string">
<QUESTIONS>
<QUESTION id="7" text="What is the First Inner Question?" type="string">
<QUESTIONS>
<QUESTION id="8" text="What is another inner Question?" type="string">
</QUESTION>
</QUESTIONS>
</QUESTION>
</QUESTIONS>
</QUESTION>
<QUESTION id="4" text="Where another question?" type="string">
<QUESTIONS>
<QUESTION id="5" text="What is another inner question?" type="string">
<QUESTIONS>
<QUESTION id="6" text="What is another inner question?" type="string">
</QUESTION>
</QUESTIONS>
</QUESTION>
</QUESTIONS>
</QUESTION>
</QUESTIONS>
My XAML
<Window.Resources>
<DataTemplate x:Key="StringQuestionTemplate" DataType="models:FormQuestion" >
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding Path=QuestionText}" />
<TextBox Text="{Binding Path=Answer, Mode=TwoWay}" />
<StackPanel>
<ItemsControl ItemsSource="{Binding Path=InnerQuestions}" ItemTemplateSelector="{StaticResource TemplateSelector}" />
</StackPanel>
</StackPanel>
</DataTemplate>
<templateIssue:QuestionTemplateSelector x:Key="TemplateSelector"
StringTemplate="{ StaticResource StringQuestionTemplate }" />
</Window.Resources>
<Grid>
<StackPanel Orientation="Vertical">
<ItemsControl ItemsSource="{Binding Path=Questions}" ItemTemplateSelector="{StaticResource TemplateSelector}" >
</ItemsControl>
</StackPanel>
</Grid>
Here is the QuestionTemplateSelector
public class QuestionTemplateSelector : DataTemplateSelector
{
public DataTemplate StringTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
switch (((FormQuestion)item).Type)
{
case QuestionType.StringQuestion:
return StringTemplate;
default:
return StringTemplate;
}
}
}
I would like to use the same template selector for the "InnerQuestions" as i do for the original templates, but since it is referenced after the section I am not able to(an error is thrown). So I would like to use the same DataTemplate In the "InnerQuestions" as i do for the top level questions. Is there a way to accomplish this, either templating it using a different structure?
It sounds like you need to use the HierarchicalDataTemplate Class. Something like this perhaps (assuming your Bindings are correct):
<HierarchicalDataTemplate DataType="models:FormQuestion"
ItemsSource="{Binding Path=InnerQuestions}"
ItemTemplateSelector="{StaticResource TemplateSelector}">
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding Path=QuestionText}" />
<TextBox Text="{Binding Path=Answer, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
UPDATE >>>
You also need to use a control that can display hierarchical data, like a TreeView:
<TreeView ItemsSource="{Binding TopLevelQuestions}" />

How to set selected value path to tab header text in a tab control in WPF

I am a little unclear on how I would set the SelectedValuePath of a TabControl to the text of the selected TabItems header. I feel like this should be fairly simple, and probably involves content.something but I have always been a bit confused about the Content property.
ItemTemplate — template for tab headers. Just add textblock with the same binding as in property SelectedValuePath.
<UserControl.Resources>
<XmlDataProvider x:Key="Employees" XPath="/Employees/*">
<x:XData>
<Employees xmlns="">
<Employee Name="Terry Adams" Type="FTE" EmployeeNumber="1" />
<Employee Name="Claire O&apos;Donnell" Type="FTE" EmployeeNumber="12345" />
<Employee Name="Palle Peterson" Type="FTE" EmployeeNumber="5678" />
<Employee Name="Amy E. Alberts" Type="CSG" EmployeeNumber="99222" />
<Employee Name="Stefan Hesse" Type="Vendor" EmployeeNumber="-" />
</Employees>
</x:XData>
</XmlDataProvider>
<DataTemplate x:Key="HeaderDataTemplate">
<TextBlock Text="{Binding XPath=#EmployeeNumber}" />
</DataTemplate>
<DataTemplate x:Key="ContentDataTemplate">
<TextBlock Text="{Binding XPath=#Name}" />
</DataTemplate>
</UserControl.Resources>
<TabControl ItemsSource="{Binding Source={StaticResource Employees}}"
ItemTemplate="{StaticResource HeaderDataTemplate}"
ContentTemplate="{StaticResource ContentDataTemplate}"
SelectedValue="12345"
SelectedValuePath="#EmployeeNumber"/>

Resources