2017-04-15 11 views
1

新しいWPFウィンドウクラスのスタイルを作成し、そこにいくつかの依存プロパティを作成しました。注意すべき1がShowHelpButton依存関係プロパティがVisual Studio Designerを更新しない

ある

これは、ウィンドウ上の[ヘルプ]ボタンの表示を切り替えることになっています。コードは、実行時に正常に動作しますが、デザインビューでUIを更新することができません。

ここでは、クラスの:ここで

public class MainWindowFrame : Window 
{ 
    #region DependencyProperties 

    public static readonly DependencyProperty ShowHelpButtonProperty = DependencyProperty.Register(
    "ShowHelpButton", typeof (bool), typeof (MainWindowFrame), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsRender)); 

    public bool ShowHelpButton 
    { 
    get { return (bool) GetValue(ShowHelpButtonProperty); } 
    set { SetValue(ShowHelpButtonProperty, value); } 
    } 

    #endregion 


    static MainWindowFrame() 
    { 
    DefaultStyleKeyProperty.OverrideMetadata(typeof(MainWindowFrame), 
     new FrameworkPropertyMetadata(typeof(MainWindowFrame))); 
    } 

スタイルです:

<Style x:Key="MainWindowStyle" TargetType="{x:Type abstractClasses:MainWindowFrame}"> 
    <Setter Property="HorizontalAlignment" Value="Stretch" /> 
    <Setter Property="VerticalAlignment" Value="Stretch" /> 
    <Setter Property="AllowsTransparency" Value="True" /> 
    <Setter Property="Background" Value="{StaticResource LightBlueBrush}" /> 
    <Setter Property="BorderBrush" Value="{StaticResource BlueBrush}" /> 
    <Setter Property="BorderThickness" Value="1" /> 
    <Setter Property="CornerRadius" Value="1" /> 
    <Setter Property="ResizeMode" Value="NoResize" /> 
    <Setter Property="WindowStyle" Value="None" /> 
    <Setter Property="Title" Value="New Window" /> 
    <Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="{x:Type abstractClasses:MainWindowFrame}"> 
      <Border 
       Background="{TemplateBinding Background}" 
       BorderBrush="{TemplateBinding BorderBrush}" 
       BorderThickness="{TemplateBinding BorderThickness}" 
       CornerRadius="{TemplateBinding CornerRadius}"> 
       <Grid x:Name="ContainerGrid" Background="Transparent"> 
       <Grid.RowDefinitions> 
        <RowDefinition Height="Auto" /> 
        <RowDefinition Height="*" /> 
       </Grid.RowDefinitions> 
       <Grid.Triggers> 
        <EventTrigger RoutedEvent="Grid.Loaded"> 
         <BeginStoryboard> 
          <Storyboard> 
          <DoubleAnimation 
           Storyboard.TargetProperty="Opacity" 
           From="0" 
           To="1" 
           Duration="00:00:01" /> 
          </Storyboard> 
         </BeginStoryboard> 
        </EventTrigger> 
       </Grid.Triggers> 
       <Grid Background="Transparent" MouseDown="Window_MouseDownDrag"> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="*" /> 
         <ColumnDefinition Width="Auto" /> 
         <ColumnDefinition Width="Auto" /> 
        </Grid.ColumnDefinitions> 
        <Grid Grid.Column="0"> 
         <TextBlock 
          Margin="10,3,0,3" 
          HorizontalAlignment="Left" 
          VerticalAlignment="Center" 
          Style="{StaticResource CustomTitleBarTextBlackB}" 
          Text="{TemplateBinding Title}" /> 
        </Grid> 
        <Button 
         Grid.Column="1" 
         Width="20" 
         Height="20" 
         Margin="0,0,5,0" 
         HorizontalAlignment="Right" 
         AutomationProperties.AutomationId="Help" 
         Style="{StaticResource HelpButtonStyle}" 
         Visibility="{TemplateBinding Property=ShowHelpButton, 
                Converter={StaticResource BoolToVisConverter}}" /> 
       </Grid> 

       <AdornerDecorator Grid.Row="1"> 
        <ContentPresenter x:Name="WindowContent" /> 
       </AdornerDecorator> 
       </Grid> 
      </Border> 
     </ControlTemplate> 
    </Setter.Value> 
    </Setter> 

そして最後に、ここで私はそれを使用している方法は次のとおりです。

<abstractClasses:MainWindowFrame 
x:Class="Utils.UI.NewFeaturesDialog" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:abstractClasses="clr-namespace:Utils.AbstractClasses" 
xmlns:ui="clr-namespace:Utils.UI" 
xmlns:utilResx="clr-namespace:Utils.Resources" 
Width="775" 
DataContext="{Binding RelativeSource={RelativeSource Self}}" 
ShowHelpButton="False" 
SizeToContent="Height" 
Style="{DynamicResource ResourceKey=MainWindowStyle}"> 

<Window.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary Source="/Utils;component/WPFStyles/Styles.xaml"/> 
    </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Window.Resources> 
</abstractClasses:MainWindowFrame> 

私は」一見すべてを試みた。私はこれを行うことによって、すべてのFrameworkPropertyMetadataOptionsを追加しました:

FrameworkPropertyMetadataOptions.AffectsArrange | 

FrameworkPropertyMetadataOptions.AffectsMeasure | 

FrameworkPropertyMetadataOptions.AffectsRender | 

FrameworkPropertyMetadataOptions.AffectsParentMeasure | 

FrameworkPropertyMetadataOptions.AffectsParentArrange 

は私も無駄にコールバックを追加しました。私はVisual Studio 2015を再起動しようとしました。私はVSバグだと思っていますが、何が起こっているのか誰かが考えていることを願っています。助けてくれてありがとう!

+0

テンプレートバインディングの代わりにcontroltemplateでトリガを使用して、それが役立つかどうかを確認してください。 – Liero

答えて

2

更新答え

それはその既知のデザイン時のバグのように見えます。 WPF designer not showing content assigned to custom DependencyProperty

我々は我々自身のプロキシタイプで代用ように、我々は、デザイナー内のウィンドウのデザインインスタンスを作成することはできません:サブクラス化/派生ウィンドウ オブジェクトのためにこれはバグでは、この問題に関連しているようだと報告しました。

したがって、デザイナーが派生ウィンドウタイプのインスタンスを作成できない場合は、デザイン時にバインディング(TemplateBinding)ロジックが失敗します。

テンプレートバインディングにフォールバック値を提供することは容易ではないため、このapproachを使用して、デザイン時の動作として機能するデフォルト値を提供できます。

+1

これはDataContextとは関係ありません。 TemplateBindingはこのためのものです。 – Liero

+0

合意。ちょうどあなたのコードをもう一度見ました。私はテンプレートのバインディングを見逃していました。私は私の答えを更新します。 – Ada

+0

回答が更新されました。 – Ada

0

申し訳ありません問題を再現できません。

私は通常、もっと簡単ではあるが複雑な方法で行っています。 ViewModelを別のアセンブリに配置しているので、ビューから参照するような誘惑はありません。 +すべてをスタイリングできるようにするために、私はTemplatesをGeneric.xamlに置き、App.xamlのGenericの後にロードされる別の辞書のスタイルをオーバーライドします。 ここで私は何かしら行います。

MyWindow.xaml:App.xamlで

<Window x:Class="Sandbox.MyWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:Sandbox" 
    xmlns:l="clr-namespace:ProjectLibrary;assembly=ProjectLibrary" 
    mc:Ignorable="d" d:DataContext="{DynamicResource DesignViewModel}" 
    Title="MyWindow" Height="300" Width="300"> 
<Window.Resources> 
    <l:MyViewModel x:Key="DesignViewModel" SomeButtonVisibility="Collapsed"/> 
</Window.Resources> 
<StackPanel> 
    <TextBlock Text="{Binding SomeText}"/> 
    <Button HorizontalAlignment="Center" VerticalAlignment="Center" Content="1 Button"/> 
    <Button Visibility="{Binding SomeButtonVisibility}" HorizontalAlignment="Center" VerticalAlignment="Center" Content="2 Button"/> 
    <Button HorizontalAlignment="Center" VerticalAlignment="Center" Content="3 Button"/> 
</StackPanel> 

私はApp.xaml.csでそれを処理するためにStartupURIを削除します。

using ProjectLibrary; 
using System.Windows; 

namespace Sandbox { 
public partial class App : Application { 
    MyWindow w; 
    MyViewModel vm; 

    public App() { 
     w = new MyWindow(); 
     //You also can pass Action to open new window of some sort here 
     //or other things, that VM can't have access to 
     vm = new MyViewModel(true); 
     w.DataContext = vm; 

     w.Show(); 
    } 
    } 
} 

MyViewModel:

using System.Windows; 

namespace ProjectLibrary 
{ 
public class MyViewModel : Notifiable 
{ 
    public MyViewModel() :this(false) { 
    } 

    public MyViewModel(bool Execute) { 
     if (Execute) { 
      SomeText = "Execution data"; 
     } else { 
      SomeText = "Design Data"; 
     } 
     SomeButtonVisibility = Visibility.Visible; 
    } 

    private string _someText; 
    public string SomeText { get { return _someText; } set { _someText = value; RaisePropertyChanged("SomeText"); } } 

    private Visibility _someButtonVisibility; 
    public Visibility SomeButtonVisibility { get { return _someButtonVisibility; } set { _someButtonVisibility = value; RaisePropertyChanged("SomeButtonVisibility"); } } 
} 
} 

Notifiable.cs:

using System.ComponentModel; 

namespace PTR.PTRLib.Common { 
public class Notifiable : INotifyPropertyChanged { 
    public event PropertyChangedEventHandler PropertyChanged; 
    protected void RaisePropertyChanged(string propertyName) { 
     // take a copy to prevent thread issues 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 
} 

App.xaml:

<Application x:Class="Sandbox.App" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:Sandbox"> 
<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="Themes/Generic.xaml"/> <!-- Default Styles --> 
      <ResourceDictionary Source="Themes/StyleRes.xaml"/> <!-- ColorTemplates --> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

テンプレート/ Generic.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
       xmlns:local="clr-namespace:Sandbox"> 
<Style TargetType="{x:Type local:MyWindow}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type Window}"> 
       <Grid> 
        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"> 
         <AdornerDecorator> 
          <ContentPresenter/> 
         </AdornerDecorator> 
        </Border> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
    <Style.Triggers> 
     <Trigger Property="ResizeMode" Value="CanResizeWithGrip"> 
      <Setter Property="Template" Value="{StaticResource WindowTemplateKey}"/> 
     </Trigger> 
    </Style.Triggers> 
</Style> 

テーマ/ StyleRes。XAML:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
       xmlns:local="clr-namespace:Sandbox"> 

<Style TargetType="{x:Type local:MyWindow}"> 
    <Setter Property="Foreground" Value="Red"/> 
    <Setter Property="Background" Value="LightBlue"/> 
</Style> 
<Style TargetType="{x:Type Button}"> 
    <Setter Property="Foreground" Value="Red"/> 
    <Setter Property="Background" Value="LightBlue"/> 
</Style> 

私は、WPFの専門家ではないんだけど、これは私がデータベース+ WPFインターフェース(素敵な1)をプログラムの1.5年間のコースで学んだものです。

+0

Aww ... Sharada Gururajが知られているように、既知のバグです。今私は以前のようなものに対処し、解決策が見つからなかったことを覚えています。だから、私はユーザーコントロールですべてをやり始めましたが、私はあなたが私のパターンで簡単にCustomControlsを行うことができることに気付きました。 UserControlとしてすべてのコントロールをプロトタイプしてから、コピー/貼り付けしてCustomControlを作成できます。後でテンプレートを作成してコントロールを再利用するのは簡単です。 –

+0

あなたの返信ありがとう!これは回避策として機能する可能性がありますが、唯一の問題は、xamlコードを含む別のクラスでMyWindowを継承したいので、MyWindowを設計するすべてのコードを.csファイルで実行する必要があることです別のxamlファイルでxamlを使って定義されたクラスを継承する)。私は本当にcsファイルで自分のUIコードをすべて作成したくありません。 –

0

私はこれが短い答えかもしれないことを知っています....しかし、設計時にのみ問題が起きていると思っていますが、デザイナーのデータコンテキストの問題が原因である可能性があります。あなたはd:DataContextを試しましたか?

d:DataContext ="{d:DesignInstance {x:Type nameSpace:ViewModel}, IsDesignTimeCreatable=True}" 

https://www.codeproject.com/tips/879109/using-design-time-databinding-while-developing-a-w

関連する問題