0

I've created a custom control that is styled and configures in its own XAML sheet. Databindings in this control uses a specific object (CProject class).

Just to clarify, the control is a project frame, that has controls for settings and a canvas that will be the workspace for each/any project.

The project control (IPProjectPanel) inherits "Frame", and also adds a "settings" stack panel to its children list which in turn contains controls for - well, settings.

The CProject class however, is the pure functional part, with no UI interaction or handling whatsoever. So, I need to "plug" an instance of CProject into every unique project that can be active. So, I want to set a specific instance of CProject as datacontext to every IPProjectPanel instance in a tabpanel. Either I want to set the datacontext by code, or have it created by settings datacontext in XAML, and retrieving it after it has been initialized.

The problem though, is that I cant quite figure out either.

Here is a snippet of the style of the IPProjectPanel in XAML, that uses the approach to set datacontext in XAML:

  <Style TargetType="{x:Type ip:IPProjectGrid}">
    <Setter Property="OverridesDefaultStyle"
        Value="True" />
    <Setter Property="SnapsToDevicePixels"
        Value="True" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ip:IPProjectGrid}">
                <Grid Background="White"  
                      HorizontalAlignment="Stretch" 
                      VerticalAlignment="Stretch" 
                      Margin="0">
                    <!---->
                    <Grid.DataContext>
                        <ipp:CProject></ipp:CProject>
                    </Grid.DataContext>

                    <StackPanel x:Name="PART_settingsPanel" 
                                HorizontalAlignment="Right" 
                                VerticalAlignment="Stretch"
                                MinWidth="300" Background="Gray">

                        <GroupBox Header="Project settings">
                            <StackPanel>

  ....

  </style>

Here it is set as a context to Grid, but I'd like to have it as a context of the actual class (IPProjectPanel).

So, the IPProjectPanel instance is created by code (for now..), and I need to retrieve the CProject instance (or set one) so that I can work with it.

I'd like to keep to C#/WPF ways to do stuff, as this app is also training for WPF and C# concepts and such. So the "best C#-WPF" way to do it, is very welcome, but a solution either way!

Thank you for your time.

4

2 に答える 2

1

したがって、一般に、datacontext は主に ViewModel 用であることが意図されており、実際に WPF は MVVM (Model View ViewModel) スタイルのアプリケーションを実行するために設定されています。習得するのは実際にはかなり簡単ですが、「最高の C#-WPF」方法を探している場合は、時間をかけて MVVM を学んでください。それは本当にかなり簡単です。

CodeProject の簡単な例:

http://www.codeproject.com/Articles/165368/WPF-MVVM-Quick-Start-Tutorial

Microsoft から (やや読みにくい):

http://msdn.microsoft.com/en-us/library/gg405484(v=pandp.40).aspx

于 2013-02-07T14:37:01.027 に答える
0

現在、この設定を行っている方法では、厄介なバグが発生する可能性があります。DataContextテンプレートのスコープ外でオブジェクト インスタンスにアクセスする予定がない限り、テンプレート内でオブジェクト インスタンスを宣言しないでください。そうすることでCProject、コントロールを視覚的に再ロードする必要があるときはいつでもクラスの新しいインスタンスを作成することになり (タブの変更など) CProject、完全に別のインスタンスを画面に表示しながら、コードで古いインスタンスを参照することになる可能性があります。DataContextテンプレートにないオブジェクト (つまり) を宣言しても問題ありませんWindow.DataContext

各コントロール インスタンスで独自のインスタンスを作成する場合は、コンストラクターのコードでそれを行い、それをコントロールのプロパティとして公開して、テンプレート内でCProjectバインドできるようにすることをお勧めします。Grid.DataContextこれをコントロール自体のプロパティに設定しないでくださいDataContext。これにより、XAML で宣言されているコントロールに設定されている暗黙的なソース バインディングが、継承された をオーバーライドすることによって壊れますDataContext

Grid.DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=PropertyWithCProject}"

CProjectおそらく、インスタンスを外部で制御し、それらをコントロール インスタンスに渡したいと思うでしょう。これを行うには、コンテナー ViewModel クラス (MVVM パターン) でそれらを作成し、これをDataContextすべてのカスタム コントロールを含む何かの上に設定します。次に、個々のCProjectsまたはそれらのコレクションを公開し、コントロールをそれらにバインドできますDataContexts

于 2013-02-07T15:27:57.267 に答える