如何从viewmodel为动态控件设置非依赖项属性

时间:2010-12-07 17:23:33

标签: wpf

我知道我的主题有点令人困惑,这或者是因为我完全迷惑自己,以至于我错过了一个简单的解决方案,或者这确实是一个难以解决的问题。

我的视图的一部分是一组基于viewmodel中的可观察列表创建的选项卡。每个选项卡都有几个嵌入式控件,其中一个是RichTextBox。 RichTextBox的一个重要限制是Document不是依赖属性,我知道一个解决方案是对控件进行子类化,只需添加一个依赖属性。

我已经从几个方向解决了这个问题,而且由于我对.net的了解仍然不断增长,我不会取得进展。我相信我最大的问题是视图和VM的分离。我的视图将VM作为数据源,并且正确生成了原始的8个项目组。但是,即使可观察列表中使用的类将flowdocument作为其项之一,也没有XAML方法将该流文档绑定到RichTextBox。似乎没有TabControl的newTabAdded类型事件,RichTextBox的Initialized事件似乎甚至没有成为View中后面的代码。即使我可以在后面的代码中捕获一个有用的事件,我似乎也无法理解Relay命令如何在没有实现ICommand源的控件上工作以将事件传递给我的VM。

所以我的问题是,使用哪种模式或类允许在VM中访问基于可观察列表动态创建的视图中的特定控件,并且可以在运行时动态更改?我在VS2010 Professional for .net4.0下这样做,并且也可以进行混合。我目前的要求是只将文档设置一次,但在完美的世界中,我希望能够更改文档。

这是当前的XAML

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Luna" 
    xmlns:CustomControlLibrary="clr-namespace:CustomControlLibrary;assembly=CustomControlLibrary" 
    x:Class="ClientUI.View" 
    Title="ViewWindow" Height="350" Width="525">
<Window.Resources>
    <DataTemplate x:Key="BSwitchTemplate">
        <StackPanel x:Name="Switch_Listing">
            <Button Content="{Binding SwitchInstance.boxName, Mode=OneWay}" Width="75" Style="{DynamicResource swmainbuttonTemplate}">
                <Button.Resources>
                    <Style x:Key="ButtonFocusVisual">
                        <Setter Property="Control.Template">
                            <Setter.Value>
                                <ControlTemplate>
                                    <Rectangle Margin="3" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                    <LinearGradientBrush x:Key="ButtonNormalBackgroundFill" EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FFFFFFFF" Offset="0"/>
                        <GradientStop Color="#FFF0F0EA" Offset="0.9"/>
                    </LinearGradientBrush>
                    <SolidColorBrush x:Key="ButtonBorder" Color="#FF003C74"/>
                    <Style x:Key="swmainbuttonTemplate" TargetType="{x:Type Button}">
                        <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
                        <Setter Property="Background" Value="{StaticResource ButtonNormalBackgroundFill}"/>
                        <Setter Property="BorderBrush" Value="{StaticResource ButtonBorder}"/>
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                        <Setter Property="HorizontalContentAlignment" Value="Center"/>
                        <Setter Property="VerticalContentAlignment" Value="Center"/>
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type Button}">
                                    <Microsoft_Windows_Themes:ButtonChrome x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Fill="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" RenderDefaulted="{TemplateBinding IsDefaulted}" SnapsToDevicePixels="true" ThemeColor="NormalColor">
                                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                    </Microsoft_Windows_Themes:ButtonChrome>
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsKeyboardFocused" Value="true">
                                            <Setter Property="RenderDefaulted" TargetName="Chrome" Value="true"/>
                                        </Trigger>
                                        <Trigger Property="ToggleButton.IsChecked" Value="true">
                                            <Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
                                        </Trigger>
                                        <Trigger Property="IsEnabled" Value="false">
                                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </Button.Resources>
            </Button>
        </StackPanel>
    </DataTemplate>
    <DataTemplate x:Key="Template_swTabHeader">
        <Grid Height="Auto" Width="Auto">
            <TextBlock TextWrapping="Wrap" Text="{Binding SwitchInstance.boxName, Mode=OneWay}" FontFamily="Times New Roman" FontSize="13.333" HorizontalAlignment="Center" Width="Auto" VerticalAlignment="Center"/>
        </Grid>
    </DataTemplate>
    <DataTemplate x:Key="Template_swTabContent">
        <Grid>
            <RichTextBox x:Name="richTextBox" Margin="0,0,8,23.84" FontFamily="Lucida Console" Initialized="AssignDocument">
            </RichTextBox>
            <CustomControlLibrary:CLI_EntryBox HorizontalAlignment="Stretch" Height="20.5" Margin="2,0,8,0" TextWrapping="Wrap" Text="CLI_EntryBox" VerticalAlignment="Bottom"/>
        </Grid>
    </DataTemplate>
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource VMDataSource}}">
    <Grid.RowDefinitions>
        <RowDefinition Height="0.552*"/>
        <RowDefinition Height="0.448*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="0.454*"/>
        <ColumnDefinition Width="0.546*"/>
    </Grid.ColumnDefinitions>
    <ListBox x:Name="mainswitchlist" HorizontalAlignment="Left" Margin="8,8,0,34.5" Width="105" SelectionMode="Multiple" ItemTemplate="{DynamicResource BSwitchTemplate}" ItemsSource="{Binding fabric_switches}" FontFamily="Times New Roman" Grid.RowSpan="2" />
    <TabControl x:Name="swTabs" Margin="117,8,51,34.5" Grid.ColumnSpan="2" ItemsSource="{Binding fabric_switches}" ItemTemplate="{DynamicResource Template_swTabHeader}" ContentTemplate="{DynamicResource Template_swTabContent}" Grid.RowSpan="2" DataContext="{StaticResource VMDataSource}" SelectionChanged="swTabs_SelectionChanged" />
    <Button Content="Button" Grid.Column="1" Height="26" HorizontalAlignment="Left" Margin="242,18,0,0" Name="button1" VerticalAlignment="Top" Width="27" />
</Grid>

1 个答案:

答案 0 :(得分:0)

几个选项:

  1. 附加行为
  2. EventSetter ItemContainerStyleTabControl TabItem使用{{1}}在每个{{1}}加载时执行某些逻辑。