我有一個MainWindow.xaml,MainwindowViewModel.cs,HaemogramReport.xaml和HaemogramReport.xaml.cs。我的項目中也有其他文件,但問題在於上述四個文件。 我在這裏發佈最小代碼,以便其他人可以發現問題。在WPF綁定不按預期工作
現在HaemogramReport.xaml我宣佈一些控件像Grid
,TextBox
,TextBlock
,Rectangle
,Border
,ContentControl
等
例如HaemogramReport.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>
當我點擊任何的上述聲明元素中的元素將引發名爲Root
的網格的mousedown事件。
該事件處理程序在HaemogramReport.xmal.cs
中。那就是:
private void Object_Selection(object sender, MouseButtonEventArgs e)
{
var mouseWasDownOn = e.Source 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;
}
MainWindowViewModel mwvm = new MainWindowViewModel();
mwvm.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);
}
在鼠標按下電網的處理器命名Root
,我說mwvm.SelectedObj = mouseWasDownOn;
SelectedObj是在MainwindowViewModel.cs
聲明類型FrameworkElement的的屬性如下:
private FrameworkElement selectedObj;
public FrameworkElement SelectedObj
{
get
{
return selectedObj;
}
set
{
selectedObj = value;
OnPropertyChanged("SelectedObj");
}
}
現在我的主窗口我有例如一個網格和一個文本框在裏面。有問題的綁定在這裏聲明。 XAML的樣子:
<Window.DataContext>
<vm:MainWindowViewModel />
</Window.DataContext>
<Grid DataContext="{Binding SelectedObj, UpdateSourceTrigger=PropertyChanged}">
<TextBox Text="{Binding Text, UpdateSourceTrigger=PropertyChanged, TargetNullValue='null', FallbackValue='Error'}"/>
</Grid>
當使用上面的代碼,我總是在上面的文本框中的文本Error
。
當時我認爲這可能是綁定錯誤的第一次機會,讓我改變了我的MainWindowViewModel.cs
如下:
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");
}
}
}
作出上述改變後,當我跑我的項目,我可以在文本框中看到123
但當我點擊任何元素時,文本框中的文本不會改變。
現在這裏的問題是,如果它的綁定錯誤,那麼爲什麼在第二個例子中,我在文本框中獲得123
,而在第一個示例中,我獲得Error
- 回退值。
如果它不是一個綁定錯誤,那麼上述代碼中的問題是什麼?
更新
當我調試,我發現SelectedObj
get
一部分不會被調用。但我不知道爲什麼?
更新 - 裏德科普塞
這是我的新類:
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);
}
}
我用它喜歡:
private void Object_Selection(object sender, MouseButtonEventArgs e)
{
DesignMethods.FindCurrentlyClickedElement(Root, e, this.DataContext as MainWindowViewModel);
}
2天前我問了這個問題。現在我已經在一個新類中移動了Object_Selection,這樣我就可以在很多地方使用它了。此外,我已將此方法標記爲「靜態」。我不能使用'this'。所以我想我應該通過'MainWindowViewModel'的Current Instance,並且我已經這樣做了。但是我仍然沒有對輸出做任何改變。 – Khushi
有關更多詳細信息,請參閱更新後的問題。另外我在xaml中聲明瞭我的datacontext。這會影響你提到的代碼嗎? – Khushi
@Khushi您確定要更改虛擬機的正確實例嗎?如果你在setter中放置一個斷點,你會看到這個變化嗎? –