Set property of ViewModel using setter within some

2019-09-13 03:15发布

I tried to google but all problems had related heading but problem context different. My problem is that I have a DataTrigger which gets triggered when certain property has a certain value i-e IsDockPanelVisible has true/false (different triggers for each value) in my case. Now when it gets triggered, it should set the value of Width - a property defined in ViewModel. Here is my specific code:

<Style.Triggers>
            <DataTrigger Binding="{Binding IsDockPanelVisible}" Value="False">
                <Setter Property="mainWindowViewModel.Width" Value="Auto">
                </Setter>
            </DataTrigger>
            <DataTrigger Binding="{Binding IsDockPanelVisible}" Value="True">
                <Setter Property="mainWindowViewModel.Width" Value="7*"></Setter>
                <Setter Property="MinWidth">
                    <Setter.Value>
                        <MultiBinding Converter="{StaticResource StringSumtoIntConvert}">
                            <Binding ElementName="cdLblNotificationsHeader" Path="MinWidth"/>
                            <Binding ElementName="cdBtnNotificationsClose" Path="ActualWidth"/>
                        </MultiBinding>
                    </Setter.Value>
                </Setter>
            </DataTrigger>
</Style.Triggers>

Here is complete code:

<Window x:Class="EmbroidaryManagementSystem_V2._0.View.MainWindow"
    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:EmbroidaryManagementSystem_V2._0.View"
    xmlns:adf="clr-namespace:EmbroidaryManagementSystem_V2"
    xmlns:collectionVM="clr-namespace:EmbroidaryManagementSystem_V2._0.ViewModel.CollectionsViewModel"
    xmlns:helperClasses="clr-namespace:EmbroidaryManagementSystem_V2._0.HelperClasses"
    xmlns:mainWindowVM="clr-namespace:EmbroidaryManagementSystem_V2._0.ViewModel.UIViewModel"
    mc:Ignorable="d"
    Title="Khalil Embroidery Management System" Height="655.512" Width="1135.159" FontSize="24" 
    WindowStartupLocation="CenterScreen" MinWidth="200" MinHeight="300" 
    Icon="/EmbroidaryManagementSystem V2.0;component/Images/KhalilEmbroideryLogonobackgrnd2.png"
    >
<Window.DataContext>
    <!--<collectionVM:ClientCollectionVM/>-->
    <mainWindowVM:MainWindowViewModel/>
</Window.DataContext>
<Window.Resources>
    <helperClasses:StringSumtoIntConverter x:Key="StringSumtoIntConvert"/>
    <ControlTemplate x:Key="DockedPanelButtonTemplate" TargetType="{x:Type Button}">
        <ControlTemplate.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background" Value="Black"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

    <Style x:Key="DockedPanelButton" TargetType="Button">
        <Setter Property="LayoutTransform">
            <Setter.Value>
                <RotateTransform Angle="90"/>
            </Setter.Value>
        </Setter>
        <!--<Setter Property="Template" Value="{StaticResource DockedPanelButtonTemplate}"/>-->
        <Setter x:Name="border" Property="BorderBrush" Value="DodgerBlue"/>
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="BorderBrush" Value="Aquamarine"/>
                <Setter Property="Background" Value="Yellow"/>
            </Trigger>
        </Style.Triggers>
    </Style>

    <!--<mainWindowVM:MainWindowViewModel x:Key="WindowViewModel"/>-->
    <Style x:Key="OnIsDockPanelVisibleChangedGridBehaviour" TargetType="Grid">
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsDockPanelVisible}" Value="False">
                <Setter Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding IsDockPanelVisible}" Value="True">
                <Setter Property="Visibility" Value="Visible"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>

    <Style x:Key="OnIsDockPanelVisibleChangedPanelColumnBehaviour" TargetType="ColumnDefinition">
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsDockPanelVisible}" Value="False">
                <Setter Property="mainWindowViewModel.Width" Value="Auto">
                </Setter>
            </DataTrigger>
            <DataTrigger Binding="{Binding IsDockPanelVisible}" Value="True">
                <Setter Property="mainWindowViewModel.Width" Value="7*"></Setter>
                <Setter Property="MinWidth">
                    <Setter.Value>
                        <MultiBinding Converter="{StaticResource StringSumtoIntConvert}">
                            <Binding ElementName="cdLblNotificationsHeader" Path="MinWidth"/>
                            <Binding ElementName="cdBtnNotificationsClose" Path="ActualWidth"/>
                        </MultiBinding>
                    </Setter.Value>
                </Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>

    <Style x:Key="OnIsDockPanelVisibleChangedButtonBehaviour" TargetType="Button" 
           BasedOn="{StaticResource DockedPanelButton}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsDockPanelVisible}" Value="True">
                <Setter Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding IsDockPanelVisible}" Value="False">
                <Setter Property="Visibility" Value="Visible"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>

    <Style x:Key="OnIsDockPanelVisibleChangedGridSplitterBehaviour" TargetType="GridSplitter">
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsDockPanelVisible}" Value="True">
                <Setter Property="Visibility" Value="Visible"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding IsDockPanelVisible}" Value="False">
                <Setter Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>

    <SolidColorBrush x:Key="TransparentBackground">
        Transparent
    </SolidColorBrush>

    <Style x:Key="LeftDockedPanelButton" TargetType="Button" BasedOn="{StaticResource OnIsDockPanelVisibleChangedButtonBehaviour}">
        <Setter Property="BorderThickness" Value="0,0,0,15"/>
    </Style>

    <Style x:Key="RightDockedPanelButton" TargetType="Button" BasedOn="{StaticResource OnIsDockPanelVisibleChangedButtonBehaviour}">
        <Setter Property="BorderThickness" Value="0,8,0,0"/>
    </Style>

    <BitmapImage x:Key="LogoImage" UriSource="/Images/KhalilEmbroideryLogonobackgrnd2.png"/>
</Window.Resources>

<!--<ScrollViewer HorizontalScrollBarVisibility="Auto">-->
<Grid x:Name="mainGrid" Background="#FFD6DBE9">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition MinHeight="103"/>
    </Grid.RowDefinitions>

    <Menu Height="18" VerticalAlignment="Top" Grid.Row="0" Margin="0,0,0,0">
        <MenuItem Header="_Exit">
            <MenuItem Header="Exit"/>
        </MenuItem>
        <MenuItem Header="_View">
            <MenuItem Header="Notifications" Command="{Binding ShowDockPanelCommand}"/>
        </MenuItem>
        <MenuItem Header="Add _New">
            <MenuItem Header="Employee"/>
            <MenuItem Header="Employee Salary"/>
        </MenuItem>
        <MenuItem Header="_About">
            <MenuItem Header="About us"/>
        </MenuItem>
    </Menu>
    <ScrollViewer HorizontalScrollBarVisibility="Auto" Grid.Row="1">
        <Grid x:Name="innerContentGrid" MinHeight="500" MinWidth="600">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="20*" MinWidth="{Binding MinWidth, ElementName=tabDataEntities}"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Style="{StaticResource OnIsDockPanelVisibleChangedPanelColumnBehaviour}" Width="{Binding }"/>
            </Grid.ColumnDefinitions>

            <GridSplitter x:Name="gridSplitter" Grid.Column="1" HorizontalAlignment="Center" 
                          Width="3" Margin="0,10,0,0" Background="#FF657695" 
                          Style="{StaticResource OnIsDockPanelVisibleChangedGridSplitterBehaviour}"/>

            <Grid x:Name="gridNotificationsHeader" Grid.Column="2" Background="#FF657695" Margin="0,10,0,0" 
                  Height="30" VerticalAlignment="Top" Style="{StaticResource OnIsDockPanelVisibleChangedGridBehaviour}">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition x:Name="cdLblNotificationsHeader" 
                                      MinWidth="{Binding Width, ElementName=lblNotificationsHeader}"/>
                    <ColumnDefinition x:Name="cdBtnNotificationsClose" Width="Auto"/>
                </Grid.ColumnDefinitions>
                <Label x:Name="lblNotificationsHeader" Content="Notifications" VerticalAlignment="Top" 
                    FontSize="14.667" Height="29" Foreground="#FFEBF0EE" HorizontalAlignment="Left" Width="92"/>
                <Button x:Name="btnNotificationsClose" Content="X" 
                    Margin="0,5,8,0" VerticalAlignment="Top" Width="20" FontFamily="Verdana" HorizontalAlignment="Right" 
                        Background="Transparent" FontSize="13.333" Foreground="Black" Grid.Column="1"
                        Command="{Binding HideDockPanelCommand}"/>
            </Grid>
            <TabControl Grid.Column="0" x:Name="tabDataEntities" Margin="0,10,5,0" FontSize="12"
                    MinWidth="{Binding ElementName=TabItemOne, Path=ActualWidth}">
                <TabItem x:Name="TabItemOne">
                    <TabItem.Header>Tab Item</TabItem.Header>
                    <Grid Background="#FFE5E5E5" Margin="0,0,0,0"/>
                </TabItem>
                <TabItem Header="TabItem">
                    <Grid Background="#FFE5E5E5"/>
                </TabItem>
            </TabControl>
            <Button x:Name="btnShowNotificationsPanel" Content="Notifications" Grid.Column="2"
                    Margin="0,12,-0,0" VerticalAlignment="Top" Style="{StaticResource RightDockedPanelButton}" Background="Transparent"
                    FontSize="12" Height="Auto" HorizontalAlignment="Right" Width="Auto" 
                    Command="{Binding ShowDockPanelCommand}"/>
        </Grid>
    </ScrollViewer>
</Grid>

Width is property in my ViewModel and not FrameworkElement.Width. However, it has the same double type. ViewModel class is MainWindowViewModel and its object in XAML is mainWindowVM.

1条回答
甜甜的少女心
2楼-- · 2019-09-13 04:02

You can not set view model properties with a setter of your view.

Have a look here: Setter.Property Property.

It states that you can only uses a DependencyProperty as the value for the setter (Besides, you cannot specify a binding expression there, just a string value).

<object Property="DependencyProperty" .../>


Suggestion:

If IsDockPanelVisible is a property inside your view model, you could react to change events there in your view model, either by subscribing to INotifyPropertyChanged of this property or by calling a method in the setter of IsDockPanelVisible.

You could then set another property in your view model which is bound to the view and then achieve your desired result.

查看更多
登录 后发表回答