Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.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# 跟踪MVVM中选择的按钮?_C#_Wpf_Xaml_Mvvm - Fatal编程技术网

C# 跟踪MVVM中选择的按钮?

C# 跟踪MVVM中选择的按钮?,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我动态生成了按钮,这些按钮是根据我在VM中创建的模型创建的。每次我实例化一个模型实例时,它都会为它创建一个指定的按钮,这个按钮在整个应用程序中都会发生变化(主要是背景色) 问题是,当我没有使用MVVM(一切都在用户控件中)时,我有一个可观察的模型集合,还有一个可观察的按钮集合,但我不想处理两个可观察的集合。我在模型中添加了一个“IsSelected”bool,但我不知道这在MVVM术语中是否正确,因为我需要保留一个在网格上选择的按钮/模型实例列表 下面是我的XAML,它可能有助于描述我到底在说什

我动态生成了按钮,这些按钮是根据我在VM中创建的模型创建的。每次我实例化一个模型实例时,它都会为它创建一个指定的按钮,这个按钮在整个应用程序中都会发生变化(主要是背景色)

问题是,当我没有使用MVVM(一切都在用户控件中)时,我有一个可观察的模型集合,还有一个可观察的按钮集合,但我不想处理两个可观察的集合。我在模型中添加了一个“IsSelected”bool,但我不知道这在MVVM术语中是否正确,因为我需要保留一个在网格上选择的按钮/模型实例列表

下面是我的XAML,它可能有助于描述我到底在说什么。我将发布itemcontrol

<ItemsControl x:Name="ObjItemControl" ItemsSource="{Binding ObjCompositeCollection}">
                                    <ItemsControl.ItemContainerStyle>
                                        <Style>
                                            <Setter Property="Grid.Row" Value="{Binding Row}"/>
                                            <Setter Property="Grid.Column" Value="{Binding Column}"/>
                                        </Style>
                                    </ItemsControl.ItemContainerStyle>
                                    <ItemsControl.ItemsPanel>
                                        <ItemsPanelTemplate>
                                            <Grid DockPanel.Dock="Top" HorizontalAlignment="Stretch" 
                                             VerticalAlignment="Stretch" Name="objGrid" Grid.Row="1" 
                                             Width="{Binding MinWidth, ElementName=mainObjGrid}" 
                                             Height="{Binding Height, ElementName=mainObjGrid}"
                                             engine:GridHelper.RowCount="{Binding RowCount}"
                                             engine:GridHelper.ColumnCount="{Binding ColumnCount}" />
                                        </ItemsPanelTemplate>
                                    </ItemsControl.ItemsPanel>
                                    <ItemsControl.Resources>
                                        <DataTemplate DataType="{x:Type engine:ObjA}">
                                            <ToggleButton Content="{Binding Id}"
                                                    IsChecked="{Binding IsSelected}"
                                                    Height="{Binding ElementName=ObjItemControl, 
                                                Path=DataContext.ButtonHeightWidth}"
                                                    Width="{Binding ElementName=ObjItemControl, 
                                                Path=DataContext.ButtonHeightWidth}"
                                                    HorizontalAlignment="Stretch"
                                                    VerticalAlignment="Stretch">
                                            </ToggleButton>
                                        </DataTemplate>
                                        <DataTemplate DataType="{x:Type engine:GridLabeller}">
                                            <TextBlock Text="{Binding HeaderName}" Style="{StaticResource GridHeaders}"/>
                                        </DataTemplate>
                                    </ItemsControl.Resources>
                                </ItemsControl>
我是如何在虚拟机中使用它的——这是一个循环

                    // Create obja
                    Obja obj = new Obja();
                    obj.Id = GridHelpers.GetRowName(i)
                    ObjSource.Add(obj);
添加到复合容器中的可观察集合

    private ObservableCollection<ObjA> objSource = new ObservableCollection<ObjA>();
    public ObservableCollection<ObjA> ObjSource
    {
        get { return objSource; }
        set
        {
            objSource = value;
            OnPropertyChanged(nameof(ObjSource));
        }
    }
private observateCollection objSource=new observateCollection();
公共可观测收集对象源
{
获取{return objSource;}
设置
{
objSource=值;
OnPropertyChanged(名称为(ObjSource));
}
}
正如我所说,我希望能够在viewmodel中存储选定的按钮,这样我就可以相应地更改它们的背景颜色,但不确定如何使用MVVM实现这一点


任何帮助都将不胜感激。

在MVVM中,只有视图负责更改显示方式。因此,按钮的背景色应该在视图中处理,而不是在视图模型中处理。一个简单的场景是使用
样式的
数据触发器
,根据按钮的
IsSelected
值更改按钮的背景:


您不必更改ViewModel中的任何内容。对于更复杂的行为,您应该查看

有关样式的详细信息,请参阅

然后,在代码中,您将有一个单击事件处理程序,您可以从中检索视图模型对象:

private void ToggleButton\u单击(对象发送器,路由目标)
{
ToggleButton tb=发送方为ToggleButton;
ObjA ObjA=tb.DataContext作为ObjA;
//从这里可以对视图模型执行操作。
}

这是一个简化的示例,一般来说,使用代码隐藏并不被认为是良好的做法,您应该查看
ICommand
界面以获得更类似MVVM的构造。

在MVVM中,只有视图负责更改显示方式。因此,按钮的背景色应该在视图中处理,而不是在视图模型中处理。一个简单的场景是使用
样式的
数据触发器
,根据按钮的
IsSelected
值更改按钮的背景:


您不必更改ViewModel中的任何内容。对于更复杂的行为,您应该查看

有关样式的详细信息,请参阅

然后,在代码中,您将有一个单击事件处理程序,您可以从中检索视图模型对象:

private void ToggleButton\u单击(对象发送器,路由目标)
{
ToggleButton tb=发送方为ToggleButton;
ObjA ObjA=tb.DataContext作为ObjA;
//从这里可以对视图模型执行操作。
}

这是一个简化的示例,一般来说,使用代码隐藏并不被认为是良好的做法,您应该查看
ICommand
界面以获得更类似MVVM的构造。

嘿,Corentin窗格,存储所选按钮部件怎么样?不太确定如何执行此操作为什么要存储选定的
ToggleButton
对象?对你来说,重要的是当它被有效地选择时,它的背景会发生变化。这不仅仅是改变我所关心的背景。根据选择的按钮,我将它们分为若干组(即,在ObjA模型中设置组ID,并给它们一个通过转换器使用的组颜色)。我遍历所选按钮列表,以确定它们是否包含在我拥有的画布拖动框中(这是一个选框工具)。。。所以有多种原因。。。但在我的代码中,我只是在执行selectedbuttons.add、selectedbuttons.remove和selectedbuttons.contains。。。在那里做我需要做的事。。。如果有其他方法,也许我不需要这样做……例如,我存储了以前单击的按钮,这样我可以在拖动鼠标创建选框工具时,在etcmouse tracking上单击并拖动并高亮显示每个按钮,这也让我感到困惑,它应该在视图中还是在虚拟机中:(嘿,Corentin Pane,存储选定的按钮部分怎么样?不太确定我如何才能做到这一点为什么要存储选定的
ToggleButton
对象?对您来说,重要的是当有效地选择它时,它的背景会发生变化。我关心的不仅仅是改变背景。取决于选择的按钮d、 我将它们放入特定的组(即在ObjA模型中设置一个组ID,并给它们一个通过转换器使用的组颜色)。我迭代所选按钮列表,以确定它们是否包含在我拥有的画布拖动框中(这是一个选框工具)…因此有多个原因…但在我的代码中,我只是在做一个选择
    private ObservableCollection<ObjA> objSource = new ObservableCollection<ObjA>();
    public ObservableCollection<ObjA> ObjSource
    {
        get { return objSource; }
        set
        {
            objSource = value;
            OnPropertyChanged(nameof(ObjSource));
        }
    }