Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用ToggleButton更改ListBoxItem中的命令_C#_Wpf_Xaml - Fatal编程技术网

C# 如何使用ToggleButton更改ListBoxItem中的命令

C# 如何使用ToggleButton更改ListBoxItem中的命令,c#,wpf,xaml,C#,Wpf,Xaml,我想使用切换按钮(DevMode)更改命令,例如: 如果IsChecked为true执行命令(1) 如果IsChecked为false执行命令(2) 这是我的密码: <DockPanel> <StackPanel DockPanel.Dock="Top" Orientation="Horizontal"> <ToggleButton x:Name="DevMode" Horizonta

我想使用
切换按钮
DevMode
)更改命令,例如:

  • 如果
    IsChecked
    true
    执行命令(1)
  • 如果
    IsChecked
    false
    执行命令(2)
这是我的密码:

<DockPanel>
   <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
      <ToggleButton x:Name="DevMode" HorizontalAlignment="Right" Width="120" Height="30" Content="Developer Mode"/>
   </StackPanel>

   <ListBox DockPanel.Dock="Bottom" ItemsSource="{Binding Tiles}" SelectedItem="{Binding SelectedTile}">
      <ListBox.ItemsPanel>
         <ItemsPanelTemplate>
            <UniformGrid Width="600" Height="600" RenderTransformOrigin="0.5, 0.5"
                             Rows="{Binding Path=GetRows}"
                             Columns="{Binding Path=GetCols}">
            </UniformGrid>
         </ItemsPanelTemplate>
      </ListBox.ItemsPanel>

      <ListBox.ItemTemplate>
         <DataTemplate>
            <Image Source="{Binding Path=ImagePath}">
               <i:Interaction.Triggers>
                  <i:EventTrigger EventName="MouseUp">
                     <i:InvokeCommandAction 
                                    <!--the command which I need to change-->
                        Command="{Binding DataContext.Command1, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}"
                                    CommandParameter="{Binding DataContext.SelectedTile, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}"/>
                  </i:EventTrigger>
               </i:Interaction.Triggers>
            </Image>
         </DataTemplate>
      </ListBox.ItemTemplate>
   </ListBox>
</DockPanel>

Command=“{Binding DataContext.Command1,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ListBox}}”
CommandParameter=“{Binding DataContext.SelectedFile,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ListBox}}”/

您可以将
ToggleButton
IsChecked
属性绑定到视图模型,但在视图模型的上下文中,可能会给它一个比
IsChecked
更有意义的名称

<ToggleButton x:Name="DevMode" HorizontalAlignment="Right" Width="120" Height="30" Content="Developer Mode" IsChecked="{Binding IsChecked}"/>
在视图模型中,可以根据
IsChecked
状态决定执行哪种方法。如果您有一个can-execute委托,您也应该调整它

private bool CanExecuteMyCommand(object item)
{
   return IsChecked && Command1.CanExecute(item) || !IsChecked && Command2.CanExecute(item);
}

private void ExecuteMyCommand(object item)
{
   if (IsChecked && Command1.CanExecute(item))
      Command1.Execute(item);
   else if (!IsChecked && Command2.CanExecute(item))
      Command2.Execute(item);
}

请注意,代码假定您也在其他地方重用
Command1
Command2
。如果没有,您可以删除它们,只需使用它们的
Execute
CanExecute
委托即可。

在不破坏MVVM的情况下执行此操作的最佳方法是使用带有如下数据触发器的样式:

<ListBox DockPanel.Dock="Bottom" ItemsSource="{Binding Tiles}" SelectedItem="{Binding SelectedTile}">
<ListBox.ItemsPanel>
    <ItemsPanelTemplate>
        <UniformGrid Width="600" Height="600" RenderTransformOrigin="0.5, 0.5" Rows="{Binding Path=GetRows}" Columns="{Binding Path=GetCols}">
        </UniformGrid>
    </ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Style>
    <Style TargetType="ListBox">
            <Setter Property="ItemTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <Image Source="{Binding Path=ImagePath}">
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="MouseUp">
                                    <i:InvokeCommandAction Command="{Binding CommandB}"/>
                                    <!--Your other command-->
                                </i:EventTrigger>
                            </i:Interaction.Triggers>
                        </Image>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        <Style.Triggers>
            <DataTrigger Binding="{Binding ElementName=DevMode, Path=IsCecked}" Value="True">
                <!--Your trigger linked to the btn-->
                <Setter Property="ItemTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <Image Source="{Binding Path=ImagePath}">
                                <i:Interaction.Triggers>
                                    <i:EventTrigger EventName="MouseUp">
                                        <i:InvokeCommandAction Command="{Binding CommandA}"/>
                                        <!--Your command-->
                                    </i:EventTrigger>
                                </i:Interaction.Triggers>
                            </Image>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</ListBox.Style>


您可以将切换按钮状态传递到视图模型中,并决定在其中运行哪个命令。非常感谢,此解决方案非常有用!在我的选项中,您应该仅在gui中执行此操作,而不是在viewmodel中执行此操作,但是我同意这是一个优势case@DenisSchaf由于这种方法符合MVVM,使用其中一种取决于实际需求或个人偏好。您真的需要两个数据触发器吗?虽然您可能会争辩说,
IsChecked
是一个可为空的bool,但在单个DataTrigger中应该有一个由样式设置器设置的“默认”ItemTemplate和一个由设置器设置的ItemTemplate。我在这里看到的一个问题是,根据
IsChecked
属性重置
DataTemplate
中的整个
Trigges
集合。如果您有多个触发器,甚至可能依赖于另一个属性,此解决方案可能会快速升级。@您可以轻松更改上面的示例,仅更改命令以避免重复应用。但是我没有这样做,因为我不使用eventtrigger东西,因为我认为它们破坏了MVVM想法的一部分……有点……有时……不知何故……也许。。所以我无法测试它,决定更改整个模板。我同意你的建议和这个建议一样有效,但是这个建议使视图和模型彼此之间保持了更大的距离。当使用普通绑定而不是交互触发器时,可以很容易地在图像内部移动样式。我想在这种情况下,你可以通过把图像放在一个按钮里,很容易地避免交互触发。交互触发器始终是一种变通方法,它为控件提供了一个从未被认为可以提供的功能,就像在本例中将图像转换为按钮一样,而正确的方法是将图像放入按钮中
<ListBox DockPanel.Dock="Bottom" ItemsSource="{Binding Tiles}" SelectedItem="{Binding SelectedTile}">
<ListBox.ItemsPanel>
    <ItemsPanelTemplate>
        <UniformGrid Width="600" Height="600" RenderTransformOrigin="0.5, 0.5" Rows="{Binding Path=GetRows}" Columns="{Binding Path=GetCols}">
        </UniformGrid>
    </ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Style>
    <Style TargetType="ListBox">
            <Setter Property="ItemTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <Image Source="{Binding Path=ImagePath}">
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="MouseUp">
                                    <i:InvokeCommandAction Command="{Binding CommandB}"/>
                                    <!--Your other command-->
                                </i:EventTrigger>
                            </i:Interaction.Triggers>
                        </Image>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        <Style.Triggers>
            <DataTrigger Binding="{Binding ElementName=DevMode, Path=IsCecked}" Value="True">
                <!--Your trigger linked to the btn-->
                <Setter Property="ItemTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <Image Source="{Binding Path=ImagePath}">
                                <i:Interaction.Triggers>
                                    <i:EventTrigger EventName="MouseUp">
                                        <i:InvokeCommandAction Command="{Binding CommandA}"/>
                                        <!--Your command-->
                                    </i:EventTrigger>
                                </i:Interaction.Triggers>
                            </Image>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</ListBox.Style>