简体   繁体   中英

Unable to use MahApps style DataGrid within a UserControl

I'm pretty new to WPF, so I apologise in advance if the answer to this question is verysimple. I have looked around everywhere, but can't find an appropriate solution.

The low-down: I have an application that is using MahApps. The Windows within my app work fine. I can set style and change themes, and it applies across all the windows. The issue is that within my MainWindow I have a couple of UserControls. One of these UserControls has a DataGrid, and for some reason, the DataGrid will not take the default MahApps DataGrid style.

One other thing: My DataGrid uses DataTriggers to display different observable lists depending on a RadioButton that has been pressed. It therefore doesn't let me set the style of the DataGrid (as per the MahApps guide here: http://mahapps.com/controls/datagrid.html ).

MahApps suggestion:

<DataGrid ItemsSource="{Binding People}" Margin="10,20,10,0"
              AutoGenerateColumns="True"
              Style="{StaticResource AzureDataGrid}">

Another suggestion I found was to add the MahApps resources to the Resource dictionary of my UserControl. That didn't work, so I removed that code.

My current UserControl xaml:

<UserControl
         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" 
         xmlns:local="clr-namespace:TrayportLibrary.Home"
         xmlns:helpers="clr-namespace:TrayportLibrary.Helpers"
         xmlns:controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
         xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
         xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"              
         x:Class="TrayportLibrary.Search.SearchView"
         mc:Ignorable="d" >

<UserControl.Resources>
    <helpers:StringToVisibilityConverter x:Key="StringToVisibilityConverter"/>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</UserControl.Resources>

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <ei:CallMethodAction TargetObject="{Binding}" MethodName="LoadCollections"/>
    </i:EventTrigger>
</i:Interaction.Triggers>
<StackPanel FocusManager.FocusedElement="{Binding ElementName=SearchBox}">
    <Grid Name="MainGrid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <TextBox x:Name="SearchBox"
        Focusable="True"
        VerticalAlignment="Center"
        HorizontalAlignment="Right"
        Text="{Binding SearchInput, UpdateSourceTrigger=PropertyChanged}"
        Width="200"
        Height="25"
        BorderBrush="Black"
        BorderThickness="2"
        Grid.Column="0"
        Grid.Row="0"
        Margin="0,0,5,0"/>

        <StackPanel Grid.Column="1"
                    Grid.Row="0" 
                    Orientation="Horizontal" 
                    VerticalAlignment="Center" 
                    HorizontalAlignment="Left">
            <RadioButton GroupName="SearchSelection" 
                         Name="BookRadio"
                         Content="Books"
                         Margin="0,0,5,0"
                         IsChecked="{Binding SearchBook}"
                         Command="{Binding SetSearchCommand}"
                         CommandParameter="book"
                         Click="RadioButton_OnClick"/>
            <RadioButton GroupName="SearchSelection" 
                         Name="MemberRadio"
                         Content="Members"
                         IsChecked="{Binding SearchMember}"
                         Command="{Binding SetSearchCommand}"
                         CommandParameter="member"
                         Click="RadioButton_OnClick"/>
        </StackPanel>
        <FrameworkElement Grid.Row="1" Grid.Column="0" x:Name="Proxy"/>

        <DataGrid Name="DataGrid"
              Grid.Row="1" 
              Grid.ColumnSpan="2"
              Grid.Column="0"
              IsReadOnly="True"
              AutoGenerateColumns="False"
              Height="200"
              VerticalScrollBarVisibility="Auto"
              Visibility="{Binding Path=Text, 
                ElementName=SearchBox, 
                Converter={StaticResource 
                StringToVisibilityConverter}}">

            <DataGrid.Columns>
                <DataGridTextColumn Header="Book ID" Binding="{Binding BookID}" Visibility="{Binding DataContext.BookVisibility, Converter={StaticResource BooleanToVisibilityConverter}, Source={x:Reference Proxy}, Mode=TwoWay, NotifyOnSourceUpdated=True}"/>
                <DataGridTextColumn Header="Title" Binding="{Binding Title}" Visibility="{Binding DataContext.BookVisibility, Converter={StaticResource BooleanToVisibilityConverter}, Source={x:Reference Proxy}, Mode=TwoWay, NotifyOnSourceUpdated=True}"/>
                <DataGridTextColumn Header="Author(s)" Binding="{Binding AuthorData}" Visibility="{Binding DataContext.BookVisibility, Converter={StaticResource BooleanToVisibilityConverter}, Source={x:Reference Proxy}, Mode=TwoWay, NotifyOnSourceUpdated=True}"/>
                <DataGridTextColumn Header="Date Due" Binding="{Binding DateDue, StringFormat=dd/MM/yyyy}" Visibility="{Binding DataContext.BookVisibility, Converter={StaticResource BooleanToVisibilityConverter}, Source={x:Reference Proxy}, Mode=TwoWay, NotifyOnSourceUpdated=True}"/>
                <DataGridCheckBoxColumn Header="Out" Binding="{Binding IsOut}" Visibility="{Binding DataContext.BookVisibility, Converter={StaticResource BooleanToVisibilityConverter}, Source={x:Reference Proxy}, Mode=TwoWay, NotifyOnSourceUpdated=True}"/>
                <DataGridTextColumn Header="On Loan to" Binding="{Binding OnLoanToUserName}" Visibility="{Binding DataContext.BookVisibility, Converter={StaticResource BooleanToVisibilityConverter}, Source={x:Reference Proxy}, Mode=TwoWay, NotifyOnSourceUpdated=True}"/>
                <DataGridCheckBoxColumn Header="Lost" Binding="{Binding IsLost}" Visibility="{Binding DataContext.BookVisibility, Converter={StaticResource BooleanToVisibilityConverter}, Source={x:Reference Proxy}, Mode=TwoWay, NotifyOnSourceUpdated=True}"/>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}" Visibility="{Binding DataContext.MemberVisibility, Converter={StaticResource BooleanToVisibilityConverter}, Source={x:Reference Proxy}, Mode=TwoWay, NotifyOnSourceUpdated=True}"/>
                <DataGridTextColumn Header="Username" Binding="{Binding UserName}" Visibility="{Binding DataContext.MemberVisibility, Converter={StaticResource BooleanToVisibilityConverter}, Source={x:Reference Proxy}, Mode=TwoWay, NotifyOnSourceUpdated=True}"/>
                <DataGridTextColumn Header="Books on Loan" Binding="{Binding BooksOnLoan}" Visibility="{Binding DataContext.MemberVisibility, Converter={StaticResource BooleanToVisibilityConverter}, Source={x:Reference Proxy}, Mode=TwoWay, NotifyOnSourceUpdated=True}"/>
                <DataGridTextColumn Header="Books Overdue" Binding="{Binding BooksOverdue}" Visibility="{Binding DataContext.MemberVisibility, Converter={StaticResource BooleanToVisibilityConverter}, Source={x:Reference Proxy}, Mode=TwoWay, NotifyOnSourceUpdated=True}"/>
            </DataGrid.Columns>

            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseDoubleClick">
                    <ei:CallMethodAction MethodName="OnSelectedItem" TargetObject="{Binding}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>

            <DataGrid.Style>
                <Style>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ElementName=MemberRadio, Path=IsChecked}" Value="true">
                            <Setter Property="DataGrid.ItemsSource" Value="{Binding Members}"/>
                            <Setter Property="DataGrid.SelectedItem" Value="{Binding SelectedMember}"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding ElementName=BookRadio, Path=IsChecked}" Value="true">
                            <Setter Property="DataGrid.ItemsSource" Value="{Binding Books}"/>
                            <Setter Property="DataGrid.SelectedItem" Value="{Binding SelectedBook}"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.Style>

        </DataGrid>
    </Grid>
</StackPanel>

Any advice/code/best practise would be greatly appreciated. I'm also aware that my current xaml could probably be made simpler, but I just want to sort this issue first before I start refactoring.

Thanks in advance.

The problem is that you are overriding the style that would normally be applied to the DataGrid with your own custom style.

Your custom style can inherit setters from other styles by using the BasedOn attribute.

For example:

<Style BasedOn="{StaticResource AzureDataGrid}">

Or to inherit from the default style for the control type:

<Style BasedOn="{StaticResource {x:Type DataGrid}}">

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM