Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.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# WPF中的绑定未按预期工作_C#_Wpf_Silverlight_Xaml - Fatal编程技术网

C# WPF中的绑定未按预期工作

C# WPF中的绑定未按预期工作,c#,wpf,silverlight,xaml,C#,Wpf,Silverlight,Xaml,我有MainWindow.xaml、MainwindowViewModel.cs、hemogramReport.xaml和hemogramReport.xaml.cs。我的项目中还有其他文件,但问题在于上面提到的四个文件。 我在这里发布了最简单的代码,以便其他人能够发现这个问题 现在在hemogramreport.xaml中,我声明了一些控件,如网格,文本框,文本块,矩形,边框,内容控件等 例如,hemogramreport.xaml看起来像: <Page.DataContext>

我有MainWindow.xaml、MainwindowViewModel.cs、hemogramReport.xaml和hemogramReport.xaml.cs。我的项目中还有其他文件,但问题在于上面提到的四个文件。 我在这里发布了最简单的代码,以便其他人能够发现这个问题

现在在hemogramreport.xaml中,我声明了一些控件,如
网格
文本框
文本块
矩形
边框
内容控件

例如,
hemogramreport.xaml
看起来像:

<Page.DataContext>
    <vm:MainWindowViewModel />
</Page.DataContext>

<Grid DataContext="{Binding Source={StaticResource Settings}}" PreviewMouseDown="Object_Selection" x:Name="Root">

    <Border Style="{StaticResource BorderStyle}" x:Name="HaemogramTestBorder"
            Grid.Row="{Binding Default.HaemogramTestGridRow}" Grid.Column="{Binding Default.HaemogramTestGridColumn}"
            Grid.RowSpan="{Binding Default.HaemogramTestGridRowSpan}" Grid.ColumnSpan="{Binding Default.HaemogramTestGridColumnSpan}">
        <Grid>
            <Rectangle Fill="Transparent" x:Name="HaemogramTestRectangle"/>
            <TextBlock x:Name="HaemogramTestTextBlock"
                       Text="{Binding Default.HaemogramTestText}" Visibility="{Binding Default.HaemogramTestVisibility}"
                       Background="{Binding Default.HaemogramTestBackground, Converter={StaticResource colorToSolidColorBrushConverter}}" 
                       Foreground="{Binding Default.HaemogramTestForeground, Converter={StaticResource colorToSolidColorBrushConverter}}"
                       FontFamily="{Binding Default.HaemogramTestFontFamily, Converter={StaticResource stringToFontFamilyConverter}}"
                       FontSize="{Binding Default.HaemogramTestFontSize}" 
                       FontWeight="{Binding Default.HaemogramTestFontWeight}" FontStyle="{Binding Default.HaemogramTestFontStyle}"
                       HorizontalAlignment="{Binding Default.HaemogramTestHorizontalAlignment}" 
                       VerticalAlignment="{Binding Default.HaemogramTestVerticalAlignment}"
                       Margin="{Binding Default.HaemogramTestMargin}" />
        </Grid>
    </Border>

</Grid>
<Window.DataContext>
    <vm:MainWindowViewModel />
</Window.DataContext>

<Grid DataContext="{Binding SelectedObj, UpdateSourceTrigger=PropertyChanged}">
    <TextBox Text="{Binding Text, UpdateSourceTrigger=PropertyChanged, TargetNullValue='null', FallbackValue='Error'}"/>
</Grid>
在名为
Root
的网格的mouseDown处理程序中,我说
mwvm.SelectedObj=mousewasdown

SelectedObj是FrameworkElement类型的属性,在
MainwindowViewModel.cs
中声明如下:

private FrameworkElement selectedObj;
public FrameworkElement SelectedObj
{
    get
    {
        return selectedObj;
    }
    set
    {
        selectedObj = value;
        OnPropertyChanged("SelectedObj");
    }
}
public class MainWindowViewModel : INotifyPropertyChanged
{
    public MainWindowViewModel()
    {
        SelectedObj = txt;
    }

    TextBlock txt = new TextBlock()
    {
        Text = "123"
    };

    private FrameworkElement selectedObj;
    public FrameworkElement SelectedObj
    {
        get
        {
            return selectedObj;
        }
        set
        {
            selectedObj = value;
            OnPropertyChanged("SelectedObj");
        }
    }
}
现在在我的主窗口中,我有一个网格和一个文本框。这里声明了有问题的绑定。xaml看起来像:

<Page.DataContext>
    <vm:MainWindowViewModel />
</Page.DataContext>

<Grid DataContext="{Binding Source={StaticResource Settings}}" PreviewMouseDown="Object_Selection" x:Name="Root">

    <Border Style="{StaticResource BorderStyle}" x:Name="HaemogramTestBorder"
            Grid.Row="{Binding Default.HaemogramTestGridRow}" Grid.Column="{Binding Default.HaemogramTestGridColumn}"
            Grid.RowSpan="{Binding Default.HaemogramTestGridRowSpan}" Grid.ColumnSpan="{Binding Default.HaemogramTestGridColumnSpan}">
        <Grid>
            <Rectangle Fill="Transparent" x:Name="HaemogramTestRectangle"/>
            <TextBlock x:Name="HaemogramTestTextBlock"
                       Text="{Binding Default.HaemogramTestText}" Visibility="{Binding Default.HaemogramTestVisibility}"
                       Background="{Binding Default.HaemogramTestBackground, Converter={StaticResource colorToSolidColorBrushConverter}}" 
                       Foreground="{Binding Default.HaemogramTestForeground, Converter={StaticResource colorToSolidColorBrushConverter}}"
                       FontFamily="{Binding Default.HaemogramTestFontFamily, Converter={StaticResource stringToFontFamilyConverter}}"
                       FontSize="{Binding Default.HaemogramTestFontSize}" 
                       FontWeight="{Binding Default.HaemogramTestFontWeight}" FontStyle="{Binding Default.HaemogramTestFontStyle}"
                       HorizontalAlignment="{Binding Default.HaemogramTestHorizontalAlignment}" 
                       VerticalAlignment="{Binding Default.HaemogramTestVerticalAlignment}"
                       Margin="{Binding Default.HaemogramTestMargin}" />
        </Grid>
    </Border>

</Grid>
<Window.DataContext>
    <vm:MainWindowViewModel />
</Window.DataContext>

<Grid DataContext="{Binding SelectedObj, UpdateSourceTrigger=PropertyChanged}">
    <TextBox Text="{Binding Text, UpdateSourceTrigger=PropertyChanged, TargetNullValue='null', FallbackValue='Error'}"/>
</Grid>
在运行项目时进行上述更改后,我可以在文本框中看到
123
,但当我单击任何元素时,文本框中的文本不会更改

现在的问题是,如果这是一个绑定错误,那么为什么在第二个示例中,我在文本框中得到
123
,而在第一个示例中,我得到
error
——回退值

如果这不是绑定错误,那么上面代码中的问题是什么

更新

调试时,我发现从未调用
SelectedObj
get
部分。但我不知道为什么

更新--Reed Copsey

这是我的新课:

public class DesignMethods
{

    public static void FindCurrentlyClickedElement(DependencyObject Root, MouseButtonEventArgs e, MainWindowViewModel vm)
    {
        var mouseWasDownOn = e.OriginalSource as FrameworkElement;

        if (mouseWasDownOn != null)
        {

            foreach (Border border in FindVisualChildren<Border>(Root))
            {
                border.BorderBrush = Brushes.Transparent;
            }

            if (!(mouseWasDownOn is Border))
            {
                FindParent<Border>(mouseWasDownOn).BorderBrush = Brushes.Orange;
            }

            vm.SelectedObj = mouseWasDownOn;

        }
    }

    public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                {
                    yield return (T)child;
                }

                foreach (T childOfChild in FindVisualChildren<T>(child))
                {
                    yield return childOfChild;
                }
            }
        }
    }

    public static T FindParent<T>(DependencyObject child) where T : DependencyObject
    {
        //get parent item
        DependencyObject parentObject = VisualTreeHelper.GetParent(child);

        //we've reached the end of the tree
        if (parentObject == null) return null;

        //check if the parent matches the type we're looking for
        T parent = parentObject as T;
        if (parent != null)
            return parent;
        else
            return FindParent<T>(parentObject);
    }

}
尝试使用替代源:

var mouseWasDownOn = e.OriginalSource as FrameworkElement;

因为在处理复合控件时,属性可以是包含OriginalSource对象(在您的例子中是grid)的父对象。

我认为您的错误可能是FrameworkElement没有文本属性

编辑:尝试更新要编辑的文本的绑定

{Binding SelectedObj.Text}

问题是您正在创建ViewModel的新实例,而不是使用现有实例:

// This is not the same instance you're binding to!
// MainWindowViewModel mwvm = new MainWindowViewModel();

// Get the existing one instead
var mwvm = this.DataContext as MainWindowViewModel;
mwvm.SelectedObj = mouseWasDownOn;
但是请注意,我可能不会在这里使用术语“ViewModel”。您所做的并不是典型的MVVM场景,因为您将DataContext实例紧密耦合到视图中,耦合发生在两个方向上,这与MVVM的正常目标几乎相反


编辑:

您可能还需要更新
SelectedObj
的绑定。我建议尝试将XAML设置为:

<Grid>
    <TextBox Text="{Binding SelectedObj.Text, UpdateSourceTrigger=PropertyChanged, TargetNullValue='null', FallbackValue='Error'}"/>
</Grid>

我认为您的错误可能是使用了“公共”属性而不是DependencyProperties

正如您在Microsoft说明中所看到的

“当您定义自己的属性并希望它们支持许多 Windows演示基础(WPF)功能方面 包括样式、数据绑定、继承、动画和默认设置 值,则应将其实现为依赖项属性。“

这些是充分利用WPF提供的所有资源的正确属性类型

看看这些链接

或者简单地在google上查找依赖属性WCF

了解这些属性之间差异的另一个有用链接是

当我遇到类似问题时,我会用它


希望有帮助

不,当我调试时,我在那里保留了一个断点,我认为mouseWasDownOn中的值总是我单击的元素。我的意思是,我不认为你提到的代码是问题的原因。是的,你在某种程度上是正确的,所以我用Object替换了FrameworkElement。和对象有一个文本属性。当您将文本绑定更新为{binding SelectedObj.Text}时会发生什么?我正在检查它。输出中没有任何更改。我在两天前问过这个问题。现在我在一个新类中移动了
Object\u Selection
,这样我可以在很多地方使用它。我还将此方法标记为
静态
。我不能使用
这个
。因此,我认为应该传递
MainWindowViewModel
的当前实例,我已经这样做了。但是我仍然没有在输出中得到任何更改。请查看更新的问题以了解更多详细信息。此外,我还在xaml中声明我的datacontext。这会影响你提到的代码吗?@Khushi你确定你正在更改VM的正确实例吗?如果在setter中放置断点,是否看到更改?是的,总是调用我的setter。但是永远不会调用SelectedObj的getter。@ReedCopsey是正确的,您没有看到更新的值的原因是该值是在MainWindowViewModel的不同实例上更新的。在您的两个XAML文件中,每次都会创建一个新实例—这可以通过在MainWindowViewModel的构造函数中插入断点来看到。相反,您应该尝试在App.xaml的ResourceDictionary中定义一个MainWindowViewModel,并在两个xaml文件中将其作为静态资源引用,就像您在GramTestBorder对象中使用BorderStyle一样。这对你来说应该很清楚。