- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们有一个客户端-服务器应用程序,它需要动态构建 View 。服务器会将 XAML 字符串与数据 (Dctionary< string, string>) 一起发送到客户端,然后客户端将从接收到的 Xaml 字符串构建 View 并将数据绑定(bind)到 View 。
这是示例 XAML 字符串:
<StackPanel>
<TextBox>
<TextBox.Text>
<Binding RelativeSource="{{RelativeSource Self}}" Path="DataContext"
Converter="{{StaticResource fieldBindingConverter}}" ConverterParameter="ID_Id"
UpdateSourceTrigger="PropertyChanged">
</Binding>
</TextBox.Text>
</TextBox>
<TextBox>
<TextBox.Text>
<Binding RelativeSource="{{RelativeSource Self}}" Path="DataContext"
Converter="{{StaticResource fieldBindingConverter}}" ConverterParameter="ID_Name"
UpdateSourceTrigger="PropertyChanged">
</Binding>
</TextBox.Text>
</TextBox>
</StackPanel>
数据看起来像:
new Dictionary<string, string>
{
{"ID_Id", "1"},
{"ID_Name", "John"}
};
客户端将使用 XamlReader.Load() 构建 View ,并创建一个窗口来承载它作为内容。客户端还将接收到的数据分配给Window.DataContext
window.DataContext = dictionaryData;
由于两个 TextBox 从 Window 继承了 DataContext,Text 属性绑定(bind)到 Dictionary。绑定(bind)转换器“fieldBindingConverter”使用具有键的 ConverterParameter 从字典中获取正确的值。
因此,在首次构建 View 时,两个 TextBox 将相应地显示“1”和“John”。
当新数据到达客户端时出现问题
new Dictionary<string, string>
{
{"ID_Id", "2"},
{"ID_Name", "Peter"}
};
通过重置托管窗口的 DataContext 不会使 TextBox 上的绑定(bind)自行刷新
window.DataContext = newDictionaryData;
事实上,TextBox 的 DataContext 仍然缓存旧数据值。
似乎 TextBox 仅在首次初始化时获取其父 DataContext 的副本,之后仅使用该本地副本。
在这种情况下,拥有一个 ViewModel 并实现 INotifyPropertyChanged 似乎并不容易,因为键“ID_XX”在不同的 View 之间可能会有所不同,并且很难为这种动态性质定义一个模型类(我可以错了)。
如果每次新数据到达时都创建一个新的托管窗口(并设置 DataContext),它确实可以正常工作,因为所有 TextBox 的 DataContext 都将为新的托管窗口派生新数据。
有谁知道如何让 TextBox“刷新”其 DataContext 以获取父窗口上的新集合并“刷新”绑定(bind)?
最佳答案
在 WPF 中,我们通常不会像这样将 Window
的 DataContext
设置为一个数据类型对象...但是它是 可能。相反,我们通常会创建一个特定的类,其中包含需要显示的所有属性,并且正如您提到的那样,实现 INotifyPropertyChanged
接口(interface)。在您的情况下,我们将有一个 Staff
类型的属性,我们可以在 UI 中绑定(bind)到该属性:
public string Staff
{
get { return staff; }
set { staff = value; NotifyPropertyChanged("Staff"); }
}
然后在 XAML 中:
<Window>
<StackPanel>
<TextBox Text="{Binding Staff.Id}"/>
<TextBox Text="{Binding Staff.Name}"/>
</StackPanel>
</Window>
在这个小例子中,这不是绝对必要的,但在较大的项目中,很可能还会显示其他数据。如果您将 Window.DataContext
设置为您的 Staff
数据类型的一个实例,那么您会发现显示其他数据很棘手,例如 的集合工作人员
对象。同样,最好更新 Staff
属性,它会通知界面更新 UI,而不是更新不会更新 UI 的 DataContext
,因为它不是 '连接到接口(interface)。
它是通过 INotifyPropertyChanged
接口(interface)通知的属性更改,它会在进行属性更改时更新或“刷新”UI 控件中的值。因此,您的答案是实现此接口(interface)并确保在进行属性值更改时调用 INotifyPropertyChanged.PropertyChangedEventHandler
。
更新>>>
哇!你真的没有在听,是吗?在 WPF 中,我们不会“刷新”DataContext
,INotifyPropertyChanged
接口(interface)会在属性更改后“刷新”UI。这是解决此问题的一种可能方法:
public class CustomObject
{
public int Id { get; set; }
public string Name { get; set; }
...
}
...
Dictionary<string, string> data = new Dictionary<string, string>
{
{"ID_Id", "1"},
{"ID_Name", "John"}
...
};
...
// Implement the `INotifyPropertyChanged` interface on this property
public ObservableCollection<CustomObject> CustomObjects { get; set; }
...
然后您可以像这样填充您的 CustomObject
:
CustomObjects = new ObservableCollection<CustomObject>();
CustomObject customObject = new CustomObject();
foreach (KeyValuePair<string, string> entry in data)
{
if (entry.Key == "ID_Id") // Assuming this always comes first
{
customObject = new CustomObject();
customObject.Id = int.Parse(entry.Value);
}
...
else if (entry.Key == "ID_Name") // Assuming this always comes lasst
{
customObject.Name = entry.Value;
customObjects.Add(customObject);
}
}
...
<ListBox ItemsSource="{Binding CustomObjects}">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type DataTypes:CustomObject}">
<StackPanel>
<TextBox Text="{Binding Id}"/>
...
<TextBox Text="{Binding Name}"/>
</StackPanel>
</DataTemplate DataType="{x:Type DataTypes:CustomObject}">
</ListBox.ItemTemplate>
</Window>
现在你可以争辩说你不能因为这个原因这样做,或者你不想因为那个原因这样做,但最终,你必须这样做这样的事情可以解决您的问题。
关于c# - 刷新 WPF 中子控件的 DataContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19267924/
我正在使用 Make,并且有一个 makefile,它设置了一个变量,该变量的值需要我从父 makefile 覆盖。我尝试在父 makefile 中设置变量并使用 export 将其传递给子 make
全屏运行下面的代码片段并调整屏幕大小以查看最后一行中的图像如何堆叠/环绕。它们直接包裹在下一行的正中央。我希望它们向左环绕。 #instafeed{ text-align: center; } #
我在这个网站上找到了以下 jsfiddle,它 90% 回答了我的查询。 JSFiddle 但是我希望能够在内部 div 上包含边距。我已经尝试修改计算以考虑边距,但如果内部 div 不换行或溢出,我
我有 div(class name:xyz) 在其中插入小的 4 div (class name:ax )。我需要垂直插入前两个 div,第三个应该水平插入第一个,第四个应该垂直插入第三个。但是所有的
我有一些动态添加的 QWidgets,我想在它们发生变化时执行一些任务。 我想我不能使用 connect() 因为我还需要触发更改的 QWidget 的名称。 我如何才能同时查看更改了哪个 QWidg
我想在子操作中生成 HTML head 部分;而该页面还有许多其他子操作。 html head 部分取决于其他操作来确定应包含哪些 js/css 文件。不同的子 Action 可以共享同一个js/cs
我正在构建一个 Angular 7 应用程序。我想获取父 div 中某个 div 的“索引”或行。 我的标记如下所示: 我知道如果标记如下所示,我可以轻松做到这一点,但如果
如果我在 Ruby 中调用系统方法,它将在子 shell 中执行我的命令并输出它可以输出的所有内容。因此,如果我将其放入 file.rb 中: system 'vim' 然后运行 $ ruby
我可以对齐两个 div只需设置他们的 display至 inline-block并使用相同的 line-height如下图所示: 但是,我想要的是根据内部 div 的基线对齐两个嵌套 div,如下所示
我的父 Controller 上有一些属性,我希望我的子 Controller 可以访问这些属性。 我想像这样访问它: App.ApplicationController = Ember.Object
我有一个容器 div,里面有一个 SVG: 以及以下 CSS: svg { width: 100%; height: 1
我必须处理的事件目录是这样布置的:域包含许多 OU。这些 OU 之一被命名为“主 OU”。在这个 OU 中,有几个以全局办事处位置命名的 OU(即“芝加哥”“巴黎”)。 任何实际有血有肉的用户帐户都被
我在 NSBox 中有一个 NSTextView。我想每当 NSTextView 获得焦点时在 NSBox 周围绘制焦点环,并在 NSTextView 失去焦点时立即删除焦点环。 谢谢 最佳答案 为此
在下面的代码中,我有一个链接,其 div id 是“my-acc-hover-container”。当用户将鼠标悬停在该链接上时,一个新的部分将向下滑动,其中包含“Hello Guest”和“Logi
我正在使用 javafx 创建一个像 sqlyog 这样的应用程序。我的问题是我想添加数据库。无论何时添加,它都应该更新具有所有其他数据库的 TreeView 。出现创建数据库的对话框,给出名称并设置
我的 UIScrollView 中有几个屏幕的内容,它只能垂直滚动。 我想以编程方式滚动到包含在其层次结构中某处的 View 。 UIScrollView 移动以便 subview 位于 UIScro
我想更新已创建端口的 vif_model。我在 CLI 中使用以下命令 neutron port-update --binding:vif_model=avp 如何使用 neutron 的 pyth
我在一个程序中有两个查询。 查询1:我正在尝试在容器 div 的子 div 内水平对齐两个子 super 子分区。下面是我的代码,你能帮我解决这个问题吗?我已附上所需的输出。 查询2:从代码中你可以看
我在一个程序中有两个查询。 查询1:我正在尝试在容器 div 的子 div 内水平对齐两个子 super 子分区。下面是我的代码,你能帮我解决这个问题吗?我已附上所需的输出。 查询2:从代码中你可以看
我是一名优秀的程序员,十分优秀!